POV-Ray : Newsgroups : povray.programming : Improved intersection routine for CSG-Intersection objects Server Time
6 Oct 2024 13:17:56 EDT (-0400)
  Improved intersection routine for CSG-Intersection objects (Message 69 to 78 of 108)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Thorsten Froehlich
Subject: Re: [OT] Re: Improved intersection routine for CSG-Intersection objects
Date: 16 Dec 2003 16:42:50
Message: <3fdf7c5a$1@news.povray.org>
In article <3fdf63e3@news.povray.org> , Nicolas Calimet <pov### [at] freefr>
wrote:

>>   The sad thing is that sometimes the "C-way" will be slower and less
>> efficient than the "C++-way". For instance, compare C and C++ strings.
>> (Most operations are much faster in C++, not to talk about C++ strings
>> being a lot more secure with regard to memory leaking. C++ strings are
>> also a lot easier to use.)
>
>  But in what language the C++ streams are implemented internally ?
> Isn't it mostly in C and asm ?  The C libraries usually are too.

The C++ streams tend to be slow due to practically all libraries
implementing them in the simplest, not fastest manner.  Practically they
just put a layer on top of C streams, wrap it yet again, then they pull in
more locale and half of the rest of STL and easily you get a huge program if
you just use something as trivial as even a simple cout <sigh>

Guides have been written how to make C++ streams fast, but I don't think any
big STL or compiler vendor has implemented all of them yet.

>  I'm interested in this particular point since my own projects
> rely _a lot_ on labelled data (using my own C string "library").  Could you
> give an example where C++ strings clearly outperform the equivalent C code
> (if anything similar can be done) ?

The STL string, if implemented well, is extremely fast, especially if you
deal with dynamic string length and need to copy strings around.  In fact,
the strings are usually one of the best optimised things in current STL
library implementations...

>>   (It's really sad that C++ streams are still slower than C streams in
>> most compilers. When will they make an implementation which is at least
>> as fast?)
>
>  Ah ! Since I usually write GB of data, it seems that I still have
> a good reason to "kiss" C a bit longer  ;-)

It really depends.  Taker a look at povdocgen (in Perforce).  You will
notice that is reads and writes data very quickly, and it uses only STL
strings.  It really is only so "slow" processing everything because of the
massive applying of regular expressions.  The most important thing is that
STL strings make use of strings almost trivial just like it is in most
higher level languages (i.e. modern Basic variants).

    Thorsten

____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trfde

Visit POV-Ray on the web: http://mac.povray.org


Post a reply to this message

From: Nicolas Calimet
Subject: Re: [OT] Re: Improved intersection routine for CSG-Intersection objects
Date: 16 Dec 2003 17:22:28
Message: <3fdf85a4$1@news.povray.org>
>> But in what language the C++ streams are implemented internally ?
>>Isn't it mostly in C and asm ?  The C libraries usually are too.
>
> The C++ streams

	Ooops, sorry, here I was refering to STRINGS, not streams...

> The STL string, if implemented well, is extremely fast, especially if you
> deal with dynamic string length and need to copy strings around.  In fact,
> the strings are usually one of the best optimised things in current STL
> library implementations...

	Indeed those dynamic strings are what I'm interested in.  So I should
have a look at the STL then...  Still don't see how they could be faster than
some equivalent functionality in a good implementation of the C library on the
same architecture.  Maybe thanks to faster, dedicated memory management ?

	- NC


Post a reply to this message

From: Warp
Subject: Re: [OT] Re: Improved intersection routine for CSG-Intersection objects
Date: 16 Dec 2003 17:25:23
Message: <3fdf8653@news.povray.org>
Nicolas Calimet <pov### [at] freefr> wrote:
>         But in what language the C++ streams are implemented internally ?
> Isn't it mostly in C and asm ?  The C libraries usually are too.

>         I'm interested in this particular point since my own projects
> rely _a lot_ on labelled data (using my own C string "library").  Could you
> give an example where C++ strings clearly outperform the equivalent C code
> (if anything similar can be done) ?

  I think you are confusing "string" and "stream" above. They are two
quite different things... :)

  I was talking about std::string.
  Almost *any* operation on a std::string is faster than an equivalent
operation on a C string. The simplest example is getting the size
of the string.
  std::string::size() is a constant-time operation (it simply returns
the value of a variable), while strlen() goes through the entire string
to get its size. Now, imagine that the string is 100 million characters
long...

>         Ah ! Since I usually write GB of data, it seems that I still have
> a good reason to "kiss" C a bit longer  ;-)

  If you do it right, you can change from one to the other by changing
just a few lines of code (no matter how many millions of lines long is
your whole program). That's what modularity is about.
  (If you do it wrong and you want to change it, you'll have to go
through the millions of lines and change every place where it's
used... Remember y2k?-) )

-- 
#macro M(A,N,D,L)plane{-z,-9pigment{mandel L*9translate N color_map{[0rgb x]
[1rgb 9]}scale<D,D*3D>*1e3}rotate y*A*8}#end M(-3<1.206434.28623>70,7)M(
-1<.7438.1795>1,20)M(1<.77595.13699>30,20)M(3<.75923.07145>80,99)// - Warp -


Post a reply to this message

From: Nicolas Calimet
Subject: Re: [OT] Re: Improved intersection routine for CSG-Intersection objects
Date: 16 Dec 2003 19:04:51
Message: <3fdf9da3$1@news.povray.org>
>   I think you are confusing "string" and "stream" above. They are two
> quite different things... :)

	Yes, it was a mistake: writing "stream" for "string" (see my answer
to Thorsten that I posted 3 minutes before your message  :-p )

>   I was talking about std::string.
>   Almost *any* operation on a std::string is faster than an equivalent
> operation on a C string. The simplest example is getting the size
> of the string.
>   std::string::size() is a constant-time operation (it simply returns
> the value of a variable)

	This example is very trivial, and you can easily implement the same
in your own string library in C.  What I'd like to see is the performance of
creating a dynamical formatted string, similarly to vsprintf() -- but of course
without the static buffer passed as argument, which makes vsnprintf unecessary.

>   (If you do it wrong and you want to change it, you'll have to go
> through the millions of lines and change every place where it's
> used... Remember y2k?-) )

	'sed'  ;-)

	- NC


Post a reply to this message

From: Warp
Subject: Re: [OT] Re: Improved intersection routine for CSG-Intersection objects
Date: 16 Dec 2003 20:24:52
Message: <3fdfb064@news.povray.org>
Nicolas Calimet <pov### [at] freefr> wrote:
>         This example is very trivial, and you can easily implement the same
> in your own string library in C.

  The advantage of the C++-way is that a std::string is more secure
(forget about memory leaks) and its syntax is simpler.

>  What I'd like to see is the performance of
> creating a dynamical formatted string, similarly to vsprintf() -- but of course
> without the static buffer passed as argument, which makes vsnprintf unecessary.

  std::stringstream is for that.

  std::stringstream works like a std::ostream (and like a std::istream)
but instead of outputting to a file it stores things given to it onto
memory as a string. You can then get that string from it.

  Since std::stringstream is inherited from std::basic_iostream, you
can use it anywhere a std::istream or a std::ostream is expected.

-- 
#macro N(D)#if(D>99)cylinder{M()#local D=div(D,104);M().5,2pigment{rgb M()}}
N(D)#end#end#macro M()<mod(D,13)-6mod(div(D,13)8)-3,10>#end blob{
N(11117333955)N(4254934330)N(3900569407)N(7382340)N(3358)N(970)}//  - Warp -


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: [OT] Re: Improved intersection routine for CSG-Intersection objects
Date: 17 Dec 2003 05:15:18
Message: <3fe02cb6$1@news.povray.org>
In article <3fdf9da3$1@news.povray.org> , Nicolas Calimet 
<pov### [at] freefr>  wrote:

>  This example is very trivial, and you can easily implement the same
> in your own string library in C.  What I'd like to see is the performance of
> creating a dynamical formatted string, similarly to vsprintf() -- but of
course
> without the static buffer passed as argument, which makes vsnprintf
unecessary.

If you really want to use printf-style formatting in C++ (I sure do so
often), take a look at <http://www.boost.org/libs/format/index.htm>.  While
I never used it (I have my own mini-utility function for that), it does
sound like a simple solution.

    Thorsten

____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trfde

Visit POV-Ray on the web: http://mac.povray.org


Post a reply to this message

From: Wolfgang Wieser
Subject: Re: Improved intersection routine for CSG-Intersection objects
Date: 18 Dec 2003 13:51:42
Message: <3fe1f73d@news.povray.org>
Thorsten Froehlich wrote:
>> For inline functions this is true. Not so for extern linkage.
> 
> You cannot have external linkage for template functions.
> 
You can. You just have to make sure that a specialisation for the 
used type is linked in extenally. 

>> The result is lots of inline code which results in larger executables
>> and eventually even in slower code.
> 
> Only if you use containers of many different types!  Modern linkers will
> eliminate multiple identical template function instances, thus you only
> see the code bloat in the object files, but not in the final linked
> program.
> 
Correct. But all as you normally need to have all template stuff 
inline, this results in a lot of inline code duplication. 

>>>> But _not_ for real simple types. For "I quickly need a vector", using
>>>> double v[3] is still faster than anything using operator new or
>>>> applying a fancy con/destructor.
>>>
>>> Sorry, but if you need a local variable, who said you should use new???
>>>
>> So, if you need a local variable of just such a type we're talking about,
>> i.e. a class which simply contains a pointer to an internal class,
>> then the class will be allocated on the stack (okay, fast) and the
>> internal class will be allocated using operator new on the heap.
> 
> But only if there is data.  If properly designed, if there is no data, no
> memory should be allocated.  Unless you use fixed-size data in C, you will
> have exactly the same amount of work.  And there is nothing that keeps you
> from using fixed-size data in C++, except that it is bad style, in both
> languages.
> 
I have the feeling that we're not getting the point of what we want 
to tell each other... 

>> All that happens when you call the constructor and initialize your
>> class. For the normal use, this is just what you want because when
>> you pass the class to a function, it is quite fast (just increase
>> reference counter). But if the object is simply a local var you want
>> on the stack, then the overhead is considerably.
> 
> Why would you reference count the internal data of most classes?  You seem
> to be thinking about some special case, but even then, how would a
> reference counting C++ implementation be slower than a similar C
> implementation?
> 
Because the C construction does no reference counting. You allocate 
a pointer once and then use it. And the designer knows where it was 
allocated, "who" is responsible for the pointer and its lifetime. 

Yes, that's insecure like hell but faster and smaller. 
And for good designs, it even :) works...

> Well, you should really not be doing reference counting inside a class in
> the first place.  If you share data among several objects of the same
> class,
> most of the time you have a serious design problem.  And again, the
> reference counting would not work differently in C, so there is again no
> difference in overhead!
> 
I need to make an example. 

A fairly normal implementation of the class which just holds a 
pointer to an internal class. As the internal class may be shared 
among several instances, we use reference counting. 

class MyObject
{
        _MyInternalObject *o;
        MyObject(const MyObject &m) : o(m.o)
        {  if(o) o->add_reference();  }
        MyObject(params_for_obj)
        {  o=new _MyInternalObject(params_for_obj);  o->add_reference();  }
        ~MyObject()
        {  if(o) o->sub_reference();  }
};

This is fairly straight forward and how things like std::string, etc, 
work. 

Overhead at function call (call by value): just copying the pointer 
and adding a reference (i.e. ++ref_cnt;)
[Much better than call-by-value of the complete internal class but 
worse than simply passing a pointer/reference]

So, now say you need a temporary of that class: 

foo()
{
        MyObject obj(pbject_params);
        obj.do_sth();  return(obj.sth_else());
}

That will (1) allocate some bytes on the stack (fast) and then 
(2) allocate internal object using operator new (slow). 

That is what I had in mind. 

I still am the opinion that it is pretty hard if not (nearly?) impossible 
to design really fast C++ code (i.e. as fast as insecure C code) when one 
forces itself to stick to all the "good style" guidelines. (Depends on 
what one defines as "good style"). 

So, of course gained savety comes at some price. It's just to get it 
as cheap as possible. 

Wolfgang


Post a reply to this message

From: Wolfgang Wieser
Subject: Re: Improved intersection routine for CSG-Intersection objects
Date: 18 Dec 2003 13:55:43
Message: <3fe1f82f@news.povray.org>
Thorsten Froehlich wrote:

> In article <3fddcfb2@news.povray.org> , Warp <war### [at] tagpovrayorg>  wrote:
> Especially on Windos, but almost equally so on all others systems, there
> are so many specific things, trying to abstract them is a true waste of
> time
> unless a *very* small subset of all available functionality is used.  In
> short, it is much better to do one thing well than three or four things
> badly.
> 
Have a look at Qt. 

Wolfgang


Post a reply to this message

From: Wolfgang Wieser
Subject: Re: Improved intersection routine for CSG-Intersection objects
Date: 18 Dec 2003 14:06:44
Message: <3fe1fac3@news.povray.org>
Thorsten Froehlich wrote:
>> And for RTTI: I cannot imagine that a dynamic_cast has real little
>> overhead but I honestly hope that it is the case until I run a test
>> in the next days.
> 
> Effectively you only need it when using multiple inheritance.  Of course,
> if you depend on dynamic_cast heavily, you probably have some serious
> problem understanding C++.
> 
I wouldn't say that. It depends on the problem. 
Of course, virtualisation should be preferred where possible. 
Virtual function calls are cheap and fast (the ovherhead compared to 
normal external calls is negliable unless it's a just-return-value 
function in some inner loop). 

>> Okay, my observations quoted above were based on my experiences on the
>> gcc-2.7.3.2 -> gcc-2.8 transition and may very well be outdated.
> 
> One of the slowest known compilers around ... and outdated by half a
> decade.
> 
True. I just did not re-examine my observations from the past, so I am 
doing that now. 

>> So, RTTI and exceptions still introduce considerable overhead even if
>> not used.
> 
> Shitty compiler => shitty code!  You should really use professional
> compilers to base your comparisons on.  Gcc's main feature is portability,
> not performance.
> 
Heeee. gcc is by all means no "shitty compiler". But we may try using 
e.g. the intel compiler (it has -fno-rtti but no -fno-exceptions). 

Do you know how RTTI internally works? (I.e. in an "non-shitty" 
compiler.)

Wolfgang


Post a reply to this message

From: Wolfgang Wieser
Subject: Re: Improved intersection routine for CSG-Intersection objects
Date: 18 Dec 2003 14:16:52
Message: <3fe1fd24@news.povray.org>
Thorsten Froehlich wrote:

> In article <3fdce9c8@news.povray.org> , Wolfgang Wieser <wwi### [at] gmxde>
> wrote:
> 
>> First of all, the copy constructor and assignment operators will
>> introduce overhead:
>>
>> tempate<classT>
>>  auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<T>& rhs)
>>  {
>>    if (this != &rhs)
>>    {
>>      delete pointer;   // <-- if(pointer) { destruct & free }
>>      pointer = rhs.pointer;
>>      rhs.pointer = 0;
>>    }
>>    return *this;
>>  }
> 
> No, what you show introduces no overhead when used.  If you would do the
> same without an auto_ptr you would need to write exactly the same code.
> Consequently, there is no overhead - the code is just created for you
> rather than you having to write it.
> 
Well, there is no normally need to zero the pointer in the 
caller function and do all that fancy stuff. A raw pointer or reference 
will do in most cases. 

And I even can imagine situations where the fact that the pointer value 
in the caller it cleared during the call will lead to NULL ptr deref. 
Having sait that, you'll yell at me about bad design but one finds oneself 
much faster in that situation as one may think -- especially when using 
an auto_ptr as a class member. 

Wolfgang


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.