![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> That's precisely one of the reasons why I like C++'s design (even though
> I'm also aware of its flaws in other respects). Given my line of work,
Yah. Given that what I tend to do is complex interrelated data structures
with trivial amounts of math added, it doesn't seem as beneficial to me.
> even if your algorithms are ok. (OTOH this is not really a problem exclusive
> to C++, as C and many other "low-level" languages will have the exact same
> problems.)
I think that's probably true of pretty much every language. I once spent an
hour removing the loops from the professor's APL code, and the run time went
from 15 minutes to about 30 seconds. And of course one major reason you have
a DBA is that SQL can give you crappy performance even if the algorithms are
decent.
> (Btw, about the C++ program in that webpage: I think that if he had told
> gcc to generate SSE code rather than FPU code, he would have got the desired
> rounding without having to resort to inline asm...)
Maybe he was trying to use the same FPU code that the other languages were
using. SSE uses a whole different execution model, yes?
--
Darren New, San Diego CA, USA (PST)
There's no CD like OCD, there's no CD I knoooow!
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Maybe he was trying to use the same FPU code that the other languages were
> using. SSE uses a whole different execution model, yes?
Why should that matter? The compiler should optimize as well as it can,
using any means it can.
The SSE version would most probably have not been significantly faster,
but he would have got his 64-bit rounding without having to resort to
non-standard code.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> > even if your algorithms are ok. (OTOH this is not really a problem exclusive
> > to C++, as C and many other "low-level" languages will have the exact same
> > problems.)
> I think that's probably true of pretty much every language.
I was more referring to some things which in theory one shouldn't have
to worry about, and which in many languages *are* things you don't have to
worry about, but in C++ they can bite you if you don't know about them.
One concrete example which is a real shame with most C++ compilers is
memory allocation/deallocation speed. For some reason most compilers (and
very especially gcc) do a very poor job at this, even though they could
demonstrably do it much better.
For example, consider this simple program:
//-----------------------------------------------------------------------
#include <set>
int main()
{
std::set<int> numbers;
for(int i = 0; i < 10000000; ++i) numbers.insert(i);
}
//-----------------------------------------------------------------------
It does nothing else than add 10 million consecutive integers into a
balanced binary tree, and then destroys it and ends.
Compiling this program with "g++ -O3 -march=native" in my system creates
a program which in my computer takes a bit over 15 seconds to run.
Is this time spent into inserting elements and rebalancing the tree?
No. It's mostly spent in allocating memory!
Let's change the 'number' definition a bit:
std::set<int, std::less<int>, FSBAllocator<int> > numbers;
FSBAllocator is a memory allocator I have made. From a functional point
of view it doesn't change anything significant: The program still does the
exact same thing as before, and it even consumes about the same amount of
memory.
However, when I run the modified program, it only takes 2.9 seconds.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> The SSE version would most probably have not been significantly faster,
OK. It was just a guess. :-)
Science depends on changing as few things as possible. If you're doing an
experiment comparing the speed cost of abstractions, running it on different
CPUs isn't a logical thing to do. :-)
--
Darren New, San Diego CA, USA (PST)
There's no CD like OCD, there's no CD I knoooow!
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> I was more referring to some things which in theory one shouldn't have
> to worry about,
Sure. And in theory, you shouldn't have to worry about what order you list
the tables to be joined in SQL. :-) More similar than you may think, I think.
> One concrete example which is a real shame with most C++ compilers is
> memory allocation/deallocation speed.
Yep. That has always been a bane. Lots of people try to write
special-purpose allocators just for their programs which still don't do as
well as a good GC mechanism, too. (I posted a bunch of links to the actual
research a few months back.)
Allocation performance has always been a problem even long before C++ was
around. You'd certainly think people would have gotten it right by now. I
wonder why it's so hard, tho? Is it attempts to avoid fragmentation or
something?
> Is this time spent into inserting elements and rebalancing the tree?
> No. It's mostly spent in allocating memory!
I remember programs on machines with no MMU (like the Amiga) which had to
deallocate its memory on exit, when you'd exit the program and it would
spend long seconds cleaning up its memory. Even nowadays, you can sometimes
hear the disk thrash while exiting if you've started paging. :-)
> However, when I run the modified program, it only takes 2.9 seconds.
It's cool to have a language where you can change that stuff without
screwing with the compiler, yes. :-)
--
Darren New, San Diego CA, USA (PST)
There's no CD like OCD, there's no CD I knoooow!
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> http://metamatix.org/~ocaml/price-of-abstraction.html
> Very artificial benchmark to prove a point, methinks, but it's basically
> supporting what Warp says. :-)
I'm not an OCaml expert, but I'd say that benchmark is flawed -- OCaml is
supposed to give performance very similar to C++ and its very unlikely Scala
running on top of JVM to beat it. The author did use -O3 on GCC, what options
for ocamlopt?
Perhaps I should bring on Jon Harrop to the rescue. :)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
nemesis <nam### [at] gmail com> wrote:
> I'd say that benchmark is flawed
Show me one benchmark which isn't.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp <war### [at] tag povray org> wrote:
> nemesis <nam### [at] gmail com> wrote:
> > I'd say that benchmark is flawed
>
> Show me one benchmark which isn't.
The algorithm here is a standard, not much to do about it. Other than that, the
only thing one can do is use proper optimization flags for the compilers. The
famous Language Benchmark Game gives proper optimization flags for the tools
that accept it and that makes it pretty fair.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>>> even if your algorithms are ok. (OTOH this is not really a problem exclusive
>>> to C++, as C and many other "low-level" languages will have the exact same
>>> problems.)
>
>> I think that's probably true of pretty much every language.
>
> I was more referring to some things which in theory one shouldn't have
> to worry about, and which in many languages *are* things you don't have to
> worry about, but in C++ they can bite you if you don't know about them.
>
> One concrete example which is a real shame with most C++ compilers is
> memory allocation/deallocation speed. For some reason most compilers (and
> very especially gcc) do a very poor job at this, even though they could
> demonstrably do it much better.
>
> For example, consider this simple program:
>
> //-----------------------------------------------------------------------
> #include <set>
>
> int main()
> {
> std::set<int> numbers;
> for(int i = 0; i < 10000000; ++i) numbers.insert(i);
> }
> //-----------------------------------------------------------------------
>
> It does nothing else than add 10 million consecutive integers into a
> balanced binary tree, and then destroys it and ends.
>
> Compiling this program with "g++ -O3 -march=native" in my system creates
> a program which in my computer takes a bit over 15 seconds to run.
>
> Is this time spent into inserting elements and rebalancing the tree?
> No. It's mostly spent in allocating memory!
>
> Let's change the 'number' definition a bit:
>
> std::set<int, std::less<int>, FSBAllocator<int> > numbers;
>
> FSBAllocator is a memory allocator I have made. From a functional point
> of view it doesn't change anything significant: The program still does the
> exact same thing as before, and it even consumes about the same amount of
> memory.
>
> However, when I run the modified program, it only takes 2.9 seconds.
Does it do something simple, like anticipate future needs based on the
current vector size?
Regards,
John
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
John VanSickle <evi### [at] hotmail com> wrote:
> Does it do something simple, like anticipate future needs based on the
> current vector size?
My allocator can only be used to allocate elements of the same size.
It allocates larger buffers of memory and then manages a simple list of
free blocks.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |