Domain: oonumerics.org
Stories and comments across the archive that link to oonumerics.org.
Comments · 67
-
Re:Objects...If you learn about C++ before you try to pass yourself off as an authority, you won't spout easily refutable misconceptions.
C++ only becomes slower if you use certain features that have a performance impact.
And virtually every useful feature of C++ that is not in its common subset with C is one of those.
What is the performance overhead of namespaces, typesafe object creation, references, function and operator overloading, use of const ints for array sizes (more efficient than C), non-virtual methods, STL (the word "virtual" does not appear anywhere in the STL sources), support for wide characters, protected/private modifiers, etc.? While features like templates and metaprogramming have performance tradeoffs, skilled programmers can use them to make programs that are faster than the corresponding C programs.
Example: if you use exceptions, there is a performance penalty.
And if you use operator new, you use exceptions.
Firstly, this whole point is spurious because you can always use nothrow new, which was put in the standard precisely for people who want exception-free code.
Secondly, the (exception-throwing version of) new may well be faster at error handling than malloc. For the very many programs that only catch allocation errors at the top level, setting up the exception handler is just negligible part of startup costs and far faster than checking the return value from each malloc for zero.
Even if you are doing fine-grained error checking around each call to new, it's not clear whether setting up the exception handler is slower than checking for a null-returrn. It is certainly far less error-prone.
The main slow downs you will see in your average C++ program, over the corresponding C, is the use of the string class
That and <iostream>. Once, I tried programming in GNU C++ for a system with an ARM7 CPU and 288 KiB of RAM. Even after applying all the link-time space optimizations I could find, Hello World statically linked against GNU libstdc++'s <iostream> still took 180 KiB. (Dynamic linking wouldn't even have worked because libstdc++.so itself is bigger than RAM.)
Many C++ programmers use printf instead of iostream. You're perfectly free to use whichever you want, depending whether you are more concerned with code size/performance or type-safety/extensibility.
Note that C++0x has features specifically designed to support a typesafe printf, which will completely own the very type-unsafe C version.
Furthermore, C++ templates allow code re-use with exactly 0 performance loss
As I understand it, C++ compilers implement templates by making a copy of the object code for each type for which the template code is instantiated. Once you instantiate a template numerous times, your binary gets bigger, and it slows down because it has to keep loading data from storage instead of caching it in RAM. This hurts especially on handheld platforms such as the Nintendo DS, which has only 4 MiB of RAM.
I agree that Nintendo DS programmers should limit their use of templates. Not sure why the many programs which are not targeted at the Nintendo DS (Even the DSi has 4 times as much memory) shouldn't be able to generate the far-faster code made possible by template programming (See the "Was it Worth It?" section here).
Frankly, there is no valid reason for starting a new program in C in this day and age.
This is true but only
-
Re:So, does the Duct Tape Programmer...
Such as
...?Among other things, templates tend to lead to problems debugging, designs that aren't well thought out, etc.
http://www.ski-epic.com/templates_stl_rant/index.html
http://www.informit.com/articles/article.aspx?p=26017You also can't safely use the STL classes as base classes because they have no virtual destructor, so if you end up using them and need to do interesting stuff on top of them later, you can be in for a world of hurt.
Finally, if you use STL classes with mixed types that are polymorphic and expect them to behave reasonably, you're in for a world of hurt.
http://www.oonumerics.org/tmpw00/kuehl.html
Yeah, that's probably going to take up a few kilobytes of your gigabyte of RAM. Seriously, I believe this is very, very rarely a problem.
In large pieces of software coded with heavy use of templates, it can bloat code pretty dramatically. RAM isn't free.
Most threading is due to stupidity, not a real need.
I guess it depends on what you're doing. If you are writing something that doesn't need multiple threads for performance, though, you usually don't need more than about a two core CPU, either, in which case you probably have already bought the last computer you will ever need. If we're focusing most of our coding effort on those folks, we're mainly wasting time because they've also probably bought the last version of the app they will ever need.
:-)Let's face it, CPUs aren't getting any faster, for all practical purposes. Performance is reaching a plateau. This means that if software continues to grow larger and more complex at the current rate, the user experience is going to get exponentially slower. The most promising way to improve upon this is with multiple cores, but only if the software can take advantage of it. Single threaded apps need not apply.
-
Re:While there may be "newer" languages
Sorry, this is no more true. Furthermore, having personally developed several FDFT algorithm both in fortran and in C, I can tell that rivaling fortran performances isn't that difficult. IMHO undergraduates should rather learn very well how to use data structures and algorithms: rem tene, fortran sequentur...
-
Re:Only in C? Oh dear.
Not true. http://www.oonumerics.org/blitz/
It uses template metaprogramming, so any error messages you get are 7 screens long and take hours to decipher. That's probably why the technique never really caught on.
-
Re:Aging Engineers
Stuff like this:
http://boost-sandbox.sourceforge.net/libs/proto/doc/html/boost_proto/users_guide/examples/lazy_vector.html
Generic Programming in general is impossible in C# because of underpowered generics. Unless stuff like
template
void random(Container &container, Accessor const &accessor)
{
for (unsigned int i = 0; i (i) = typename Accessor::value_type(std::rand());
}
is possible in C#, this argument holds. (Note that this is an artificial example I came up with; for a good example of real-world usage, check out Adobe GIL).
Another example: http://www.gsse.at/multiprogramming/
C++'s true power lies in its templates. Templates are turing complete, meaning that they for a meta language. Using this meta language, I can adapt code to a specific situation. For example, I can have compile-time polymorphism, which is very useful when there is enough information while compiling to choose the actual type. I can have a list of factory class types, and do a call like create_image (img); which gets compiled to the actual creator function ONLY. No virtual functions, the compiler can even inline without problems. Yes, a JIT could detect that function X has been used with the same parameters for 400 seconds, but this way, I can rationalize unnecessary runtime overhead right from the start. Yet another use was to generate code paths that only differed in pixel format type. I wrote a templated version, and iterated over a list of enums at compile-time. This helped a lot in being cache friendly while not requiring to clone tons of code. Using templates, one can write scientific computing code that rivals even Fortran in terms of performance. See: http://www.oonumerics.org/blitz/
I know C# 3.0 has a functional core, and this is wonderful - many problems can be solved much easier and cleaner with functional style. Generic programming and metaprogramming are the things I sorely miss. I would really like to have a language that has all the strengths of C++, minus its weaknesses (most notably C legacy, hideous template syntax, #include files). So far, D is the closest one, but its not there yet. Also, C++ has an ENORMOUS momentum... -
Re:Finally
Well, since Java has absolutely no support for true generic programming or template metaprogramming, there is zero chance of writing a library that outperforms C++ stuff like Blitz++. People are quick to mention run-time analysis, but fail to recognize C++'s true power, which are the above two. Hell, I can write domain-specific languages in C++ whose expressions are computed at compile-time and the result applied lazily at run-time.... try to do THAT in Java. Try to mimic expression templates in Java.
Java's main performance problem is that there is a lot of stuff that shouldn't be done at runtime at all. Polymorphism fully known and determined at compile-time is a good example; in C++, I can use specialization here. In Java, the VM has to figure out somehow that this one object is NEVER recast as one of its bases. Note that C++ without generic&metaprograms has the same problem, but the key difference is that in C++, I can SOLVE this.
Also, it is appaling to see how often the type system is erroneously used to do concept-checking. "Does type X fulfill the requirements of concept Y" is reduced to "is X of type Y or a derivative of Y". An example where this is bad:
struct vector { float x, y; } // used in library A
struct Vec2f { float x, y; } // used in library B
I can't simply use a vector given by library A for API calls used in B, even though the semantics are identical. In C++, this IS possible without dangerous casting.
If Java >=7 gets true generics (and not this sad joke that internally casts to Object, or the bound type in case of bound generics), then it will be much more interesting. Until then... -
Re:uh, no.
while the ad hominem attacks, failed sarcasm, misquotations, quasi random capitalization, etc. have been fun, you still haven't answered my question: what benefit do slide rules bring? you've identified two possibilities: they have different failure modes than calculators do, and they require that the user have a good intuition for the size of the answer. however, this "number sense" is something that everybody_ who does significant amounts of calculations needs to have, so i hardly view this as being a unique benefit of slide rules. this leaves failure modes. i agree, they have different failure modes than calculators do. if you're worried about FP hardware issues, there are several packages (see http://www.oonumerics.org/oon/) that provide arbitrary precision numerics. if you're paranoid, implementing your own arbitrary precision data types is fairly straight forward. mathematica and maple both offer a way to symbolically check answers and, in the case of maple at least, you can have it do the calculations for you using its own arbitrary precision floating point types. so a single machine can perform the same calculations both with and without the FPU and at speeds far greater than any human being could. so again, what benefits do slide rules bring?
-
Not true anymore
In scientific code FORTRAN tends to be 20% faster than the best possible C++ implementation because the grammar is so simple that compilers tend to understand better the code and can vectorize or optimize it much farther than C
;
Apparently, this is not true anymore. Most scientists are writing their codes in C++ nowadays because expression templates remove the performance penalty associated with the abstraction of manipulating N dimensional matrices. (And I'm guessing that expression templates are making up for the optimization deficitances of modern compilers...) See http://osl.iu.edu/~tveldhui/papers/techniques/ for a good explaination. See http://www.oonumerics.org/blitz/benchmarks/ for some benchmarks for blitz++ vs. F77. Blitz is actually not so cutting edge anymore. There maybe better packages out there now too. Also, with the new autovectorization technologies, these comparsions might be wrong too.
Cheers
Ben -
Re:Performance, anyone?
I'm not sure what you meant by that, but many Common Lisp implementations compile and run equivalent in speed to C/C++.
Somehow, I doubt you've really read that paper very carefully. At least IMO, you're seriously mis-characterizing what it really contains. First of all, it contains no comparison to C++ at all, only to C. Second, while they use a number of Lisp compilers, they use only one C compiler -- and one that doesn't optimize terribly well either. Finally, the test code they used was, quite frankly, so trivial, that nearly any compiler for any language ever invented should be able to produce results almost indistinguishable from hand-written assembly language (in fact, if anything is surprising about the LISP code, it's the extra work required to make it competitive -- in fact, their optimized Lisp code is longer, and IMO more difficult to read, than hand-written assembly for these tasks).
I agree that Lisp's reputation for poor performance is largely undeserved. Nonetheless, this paper falls well short of showing that it's equivalent to C except, at best, in extremely limited circumstances. C, in turn, falls well short of the performance of C++. Libraries like Blitz++ allow C++ to offer substantially better performance than C. Likewise, other compilers generally offer substantially better performance from either C or C++ code. As a result, even though Lisp does far better than most people expect, C++ with a good compiler still wins by a fairly wide margin.
OTOH, I feel obliged to reiterate: the reputation for poor performance is largely undeserved. If you start with a good design, a decent implementation in Lisp will usually give perfectly acceptable performance. Compared to a program in C, it might (or might not) suffer a slight penalty in raw speed of low-level operations. OTOH, given the difference in mind-set between typical C programmers and typical Lisp programmers the overall speed of the Lisp version will often be better, because they'll do more optimization at a higher level (e.g. caching frequently-used results instead of re-computing them). Very few programs really depend primarily upon the raw speed of a few simple operations such as those examined in this paper -- architecture and design are what make the big differences.
-
application code != library code
C++ is successful for the same reason that COBOL and Microsoft Windows have been successful: because they happened to appear in the right place at the right time, and were promoted by the right people, to become entrenched.
You're half-right. C++ "won" the application development language contest for these empty reasons. However, part of its staying power comes from the fact that, sooner or later, you need a "low-level" language to actually write fast code behind a well thought-out interface, once, and call it a library. These are two vastly different purposes, and I'd agree that C++ is as ill-suited to large-scale application development as VB is to efficient library development. However, the folks out there who need fast linear algebra routines, or lean, memory-efficient text searching, or [insert well-defined write-once problem here] often choose C++ for the right reasons.
Now, there's a legion of people that will shout "use C for that!", while trotting out the same application-level arguments they always use against C++. If there are any doubts in your mind about the advantage in expressiveness C++ has over C, take a look at the Blitz scientific computing package. C++, in some cirumstances, grants a pretty magical ability to create useful abstractions with essentially no abstraction penalty. Even if the code behind the abstraction is a template swamp, the code in front of it (the application code, the code that will be read and rewritten much more often) reads clear as day, without sacrificing performance. No, it's probably not the best language it can be, but for creating powerful, ruthlessly efficient, reusable abstractions, I don't see it as having any competition whatsoever. -
Re:Should've just done it in Python/Ruby anyways
One word: Blitz++.
-
Re:Please Explain
For C this is true, but C++ has gained alot of ground on Fortran through the use of templates and template metaprogramming.
Blitz++ performs very close to or better than Fortran on many numerical calculations. -
Re:16X increase?The concept, and radical performance boost, is in line (pardon the pun) with Expression Templates for C++.
A good example is what happens when you let the compiler decide how to do aritmetic with vectors and matrixes.
Matrix a,b,c,x;
x = a + b + c;
The naked compiler, in combination with your custom Matrix class, will probably unwind the operator overloads to do something like this:
All those temporary copies and inlined loops really kill performance. // assuming a reasonable STL w/function inlining
Matrix __t1;
for(int i=0; i<a.width; i++){
for(int j=0; j<a.width; j++){
__ti[i][j] = a[i][j] + b[i][j];
}
}
Matrix __t2;
for(int i=0; i<b.width; i++){
for(int j=0; j<c.width; j++){
__t2[i][j] = __t1[i][j] + c[i][j];
}
}
x = __t2;
Now, with an expression library, it handles each arithmetic expression discretely by type. By treating the expressions, as well as the types involved, you can do more sophisticated things. In this case, the Expression Template Library solves the problem thusly:
Here the library has carnal knowledge of the data structures involved as well as order of operations to come to such a succint solution. // using ETL
for(i=0; i<a.length; i++){
x[i] = a[i] + b[i] + c[i];
}
In the case of MACSTL, its still using these principals of "vectorizing" the expressions as well as unrolling and other traditional optimization techniques. Its also going the extra mile and using processor specific code and/or C code that targets *extremely* well to PPC. For example, the above example would opitmize well using Altivec, due to the platform's built-in vector type; you wouldn't even need a loop for adding several 'vec' instances.
I wish I knew enough about MACSTL and altivec to give a hard example of a 16X speedup. I hope this gets you closer to seeing at least *where* the reducable overhead is coming from. :)
Check out Blitz++'s papers listing for more info:
http://www.oonumerics.org/blitz/papers/ -
Why limit yourself to Altivec when you have NVidia
Well the processing power of Altivec or MMX/SSE/3DNow or whatever is nowhere near the power of you newest NVidia/ATI card you have surely bought for playing Doom III. Why not use it then? Get the brook compiler! Furthemore, I see they introduce classes like vec, etc. Such classes have been already designed successfuly for C++. Why not try porting Blitz to the Altivec and/or to the GPU?
-
Re:O'Caml....the future today
I played with OCaml for a good length of time, considering whether to make it my next language for everyday use. I should also preface things by mentioning that I'm into graphics and rendering; I need fairly heavy duty numeric performance. I've also been thinking a lot about what would be my perfect language, so this has been on my mind of late - I've been reading up on Programming Language Theory papers and texts and contemplating drafting my own language spec and trying to bootstrap a compiler.
OCaml annoys me slightly because it seems so tantalizingly close to what I'm looking for but falls just short. For one, I wish it had better support for generative programing. Sure, for template like stuff you can immitate that to some extent through the polymorphism, but because it has to be generic, it still doesn't work out performance-wise. Look at the kind of stuff they can do with Blitz++. And I know there's Camlp4 and MetaOCaml, but they're really too kludgy for my taste, though still better than the insanity that is C++ template metaprogramming. (Ick!) The model that I really like is the macro systems in Lisp or Scheme. That would require a Lisp-like syntax to work, but I'm cool with that.
The other thing that bugs me a bit is that the compiler seems fairly simple in regards to optimization passes. When I've looked at assembly output from it, even with all optimizations turned on, I was surprised to see that it doesn't seem to do common subexpression elimination or strength reduction, like a common C compiler could do for you. I realize that OCaml is more functional, which constrains the compiler a bit, but there are compilers for other functional languages that manage to do flow graph analysis and optimization. (e.g. Stalin for Scheme) This lack is dissapointing in a higher level, more declarative style language like OCaml.
Finally, one other thing is that while the foreign-function interface to C is better than many other functional languages, I wish it were still better. With OCaml, it seems like you'd still need a small library in C as a shim to interface between the two languages. It would be nice if you could simply declare a function's signature, mark it as an external C function and link the library in. To deal with garbage collection, I'd borrow something like the "pin" construction from C#. I think C# and the .Net framework have a really nice model for FFI.
Of course, if you don't need such heavy duty performance, OCaml's still a great system and a fair sight better than many other functional language systems. But it's not a panacea for everything.
One more thing: if you use (X)Emacs, be sure to have a look at Tuareg Mode. -
And the point is?
Well, I agree with you. But what is the point? I mean C++ is _a low level language_ unlike Java, and will perhaps replace Fortran in coming future as the tool for (*cough*) hardcore numerics, feat you cannot expect from both Java and C#. Take a look here.
I would like answer your parent post at the same time. C++ is not an OO language. Currently emphasis is put on templates. Even programming patterns in C++ are not expressed in terms of classes, but rather in terms of templates. Please, comparing Java and the lot to C++ is like comparing apples to oranges. -
Can't wait
A good example is code like this in C++
Vector a,b,c;
. . .
c = a+2*b;
Written naively the overloaded '+' operator returns a vector object. But I don't want any object returned. I want the code to be expanded in place as
c[0] = a[0]+2*b[0]
c[1] = a[1]+2*b[1]
c[2] = a[2]+2*b[2]
Now you can do this in C++, but look at what you need to implement to do it. The code is a hideous nightmare of template metaprogramming. Of course you can do it in a language like C, but then you lose the ability to express yourself cleanly through code like 'c=a+2*b'.
It would be great, if instead, I could hook into the compiler and tell it exactly how it should handle vectors.
Of course you'd clearly need to document your code well as people reading your code would also be forced to understand the plugins. -
SympathyYou have my sympathy.
After ten years of C++ programming, I'm underwhelmed with C++. It's broken, and Strostrup is in denial about its flaws. If C++ wasn't broken, we wouldn't have needed Java or C# or Objective-C, which, after all, look a lot like C++.
The basic problem with C++ is that, alone amongst major programming languages, it has hiding without safety, which is a terrible combination. C has neither hiding nor safety. Java, Perl, Python, Ada, and LISP have hiding with safety. This has nothing to do with efficiency. There are some basic bad design decisions in C++. Some of them come from C, and some of them come from early C++. The end result is a mess.
The best the C++ community has been able to do is to impose religious dogma, in the form of "patterns", on C++ usage. This sort of works, but not very well. Witness Microsoft's endless buffer overflow problems. Switching to C++ has not helped at all.
It's not getting any better, either. The C++ language development community is dominated by people who like to do really l33t things with templates.
I wish there were something decent and mainstream to program in. (And don't go on about Eiffel or Sather or Z or Haskell; those are going nowhere.)
-
So true...You have to work much, much harder in C++ to get anywhere near FORTRAN performance, so much so that it's almost never worth the effort.
One of the most dangerous things (optimization-wise) in C++, I've found is the temporary-creation problem. You have to be insanely careful to avoid creating temporaries to get any sort of reasonable performance... (or maybe I just need a better compiler than GNU GCC?)
Templates powerful and dangerous.
Not quite sure why you would consider them dangerous, but they are Turing Complete (i.e. they are a compile-time language all of their own). Which some people have used to create this. It looks almost as fast as Fortran, but the syntax is a lot more complex than just A*B for a matrix-multiplication. -
The problem with C++D is Walter Bright's improvement on C++. Bright wrote the original Zortech C++ compiler, which was one of the first real C++ compilers, as opposed to a front-end for a C compiler. D is really too similar to the other C++ variants to get much traction.
C++ itself is undergoing a revision. But the plans for it aren't that good.
The big problem with the C++ committee is that most of the members don't want to admit the language has major problems. Neither does Strostrup, who has written that only minor corrections are needed. If that was really true, we wouldn't need all those variants on C++ (Java, D, C#, Objective-C, Managed C++, etc.)
The committee is dominated by people who like doing cool things with templates. Most of the attention is focused on new features for extending the language via templates. It's possible to coerce the C++ template system into running programs at compile time (see Blitz). Painfully. LISP went down this dead end, where the language was taken over by people who wanted to extend the language with cool macros. (See the MIT Loop Macro.) We all know what happened to LISP.
What isn't happening is any serious attempt to make C++ a safer language. C++ is the the only major language that provides abstraction without memory safety. That's why it causes so much trouble. C++ objects must be handled very carefully, or they break the memory model. This usually results in bad pointers or buffer overflows. Java, etc. are protected against that. This is the basic reason that writing C++ is hard.
It's not fundamentally necessary to give up performance for memory safety. I've written a note on "strict mode" for C++, an attempt to deal with the problem. I'm proposing reference counts with compile-time optimization, rather than garbage collection. The model is close to that of Perl's runtime, which handles this well.
Garbage collection doesn't really fit well to a language with destructors, because the destructors are called at more or less random times. Microsoft's Managed C++ does that, and the semantics of destructors are painful. With reference counts, destructor behavior is repeatable and predictable, so you can allocate resources (open files, windows) in constructors and have things work. The main problem with reference counts is overhead, but with compiler optimization support and a way to take a safe non-reference-counted pointer from a reference counted object, you can get the overhead way down and reference count updates out of almost all inner loops.
C++ itself isn't that bad. The language could be fixed. But I don't see it happening. Microsoft has gone off in a different direction with C#. SGI, HP, DEC, Bell Labs, SCO, and Sun are defunct or in no position to drive standards any more.
What C++ needs is some hardass in a position to slam a fist on the table and say "Fix it so our software doesn't crash all the time". It doesn't have one.
-
Re:What about C++?
Ever compared LAPACK to some other oonumeric library? I mean one that does NOT rely on LAPACK by itself. Check oonumerics again. Most of the linear algebra libraries rely in some way on the basic linear algebra subprograms, which are of course FORTRAN subroutines. There are ports to C++ that are as fast, but you have to code quite efficiently to actually top FORTRAN. Personally, I prefer C++ and link against the subroutines by the extern "C" directive. This involves finding the appropriate libraries, but as soon as the whole thing links, no problem. Check Todd Veldhuizens page again, and you will see a graph that shows that his Blitz++ librariy equals FORTRAN. But Blitz++ relies on expression templates in C++ which are widely known to drive you mad when you encounter them the first time. The technique Veldhuizen uses is quite complicated and relies on the fact that C++ templates are evaluated by the compiler and subsequently inlined in the code. Compared to that , even FORTRAN code is very readable.
-
Re:What about C++?
> And for the anti-FORTRAN fraction. It is still the fastest thing out there!!! Anyone who tried solving a system of linear equations containing 1000 equations knows what I mean.
I beg to differ.
At least, about the linear algebra part. There are some very fast numeric libraries out there. I mean, its not like you are wroting the code to solve the equations in Fortran yourself.
-
Re:Why do big companies want pseudo-compiled langs
May be you mean that a cast in cast is slower that a cast in C??
Of course it is.
Don't let reality disturb you
You are ignorant of how casts work in Java. That's a problem with most people that haven't worked with C++ dynamic casts. It's ok though, since the new bunch of languages target audience is just like you.
I can't. I also can't imagine a Java program full of casts. Most I have seen or written have only a few casts
How come you didn't use collections then ? What kind of application does not use collections ? only the type of applications that contain forms and widgets connected to databases. But from the moment your application contains a data model, there are collections in there, which means lots of casts.
A programmer could be productive in any language
I said exactly that. : I don't think languages play any role
Not always.
Reduntant comment. Nothing someone says is the absolute truth.
Some C++ programmer have their C++ hats down to the waist
Well, most programmers that have gone through the pain of going deep into programming languages and C++ (and they are not simple users of the language, because their company said so), have good knowledge of the deficiencies of the language. But they also know ways to solve the problems, using tools the language provides. Which is not the case with any other language.
My colleagues are always asking me how do I manage to write C++ apps without memory leaks. They don't understand it, but, even if they know C++, they have never really got into the language. They deal with it superficially. But there are some really simple rules to follow:
Anything that can be on the stack must be on the stack. For example, there is no point allocating Point classes, since they are only gonna be used for assignment.
Heap-allocated objects that are referenced by more than one position are reference counted. There are plenty of smart pointer classes around, and it is really easy to construct one, if there is none available.
Heap-allocated objects most certainly have an 'owner', which deletes them when no longer needed.
By using stack-allocated objects, RAII is possible. I don't have to explicitely close a file...I simply declare it somewhere, and it closes itself upon the function returning. This is very important, yet overlooked.
By example take STL, which many believe is an end in itself when it should be a means
Do you know any other language that the 'sort' algorithm is defined once and it is valid for all types of collections, and the algorithm does not go through a virtual interface ? there is none, except C++. If this does not tell you something, then nothing will.
About that article at the link you posted:
the overhead of Java compared to C is probably about the same magnitude as that of C relative to Fortran
It is just fud. There are numeric libraries around, like blitz++ which is just as fast as fortran for all known cases. I haven't seen any Java app that confirms this for C.
There are arguments that Java may overtake C shortly; in fact this is already happening on Linux (with respect to gcc)
Instead of replying to the abolve, the article gives the answer itself:
Intel they found that the Java performance was very reasonable compared to C (e.g, 20% slower)
Java was faster than at least one C compiler (KAI compiler on Linux)
the performance gap is small enough to be of little or no concern to programmers
Even if I was telling jokes, I wouldn't put out the above really lame arguments. 20% not being slow enough ? a fluid dynamics simulation which takes 5 working days to complete in C/Fortran, it will take 6 days with Java!!! repeat the above test N times, and you have N days of delay...and the 20% is
-
Re:Fortran is # 10The reason that Fortran is still popular in the scientific community is that it's pretty well optimised for the kind of tasks that you're likely to be doing. For example, Fortran has complex numbers as a basic data type. It's also simpler than C based languages for working with multidimensional arrays - no need to futz about with arrays of pointers or whatever, just declare a (resizable, if desired) multidimensional array. In general, the builtin functions are designed to work well on parallel architectures, so writing good parallel code isn't (quite) so much hard work.
The advantages you've listed just aren't that important against C++:
- Compex numbers aren't built-in, but who cares? C++ classes let you do anything you can do with a primitive type, both as far as optimizations are concerned and syntactically (through operator overloading)
- Likewise, multidimensional arrays can have all the syntactic sugar you want, through magical things like boost::multi_array.
- I don't know as much about the parallel stuff, but obviously a lot of thought has gone into doing that kind of thing in C++. Intel also has a compiler that will auto-parallelize C++ (and Fortran), though I've never played with it.
It's very commonly said that Fortran is faster than any other language. I don't think that's actually true. This article, written back in July '97, talks about a lot of other techniques possible in C++ to close the performance gap and even outperform Fortran. And in the seven years since, C++ compilers have improved greatly, and these techniques have been widely adopted. There are a lot more papers here.
-
I mostly disagree
There's a group of C++ programmers who are into abusing the template mechanism into a compile-time programming environment. This is not a good thing.
In your opinion. But this "group" is steadily growing larger and larger, and the number of critics are growing smaller, as they see the expressive power of templates.
One of the standard axioms of programming is that you know you have created a useful tool when others begin successfully using it for purposes other than that which was originally intended. Some people refuse to see templates as anything other than ways to write yet another typesafe-container-of-T. Others push a little farther into families of functions. Still others, like Alexandrescu and Veldhuizen and the entire Boost membership, have pushed on into a very different design. Automatic generation and maintenance of entire class hierarchies, to give a single example, is a big, big win.
Fine, you don't like it. Fair enough. I don't think anybody is trying to sell it as a silver bullet. But the expressive power of compile-time programming has been aptly demonstrated, and it's going to be around for a while. C++98 has some difficulties with it, because most of the techniques were discovered late in the game, almost by accident. Current proposals for C++0x contain a number of tweaks and extensions to make it easier.
Blindly unrollilng loops without understanding the target architecture at the instruction level is a lose on many modern superscalar machines. Newer machines tend to do loops faster than straight-line code.
This assertion is what made me respond. It's like saying, "All C programs suck," or something equally nebulous. Some machines do some loops faster than straight code under some conditions. But you won't see loop unrolling being disabled by default anytime soon, on any architecture. That decision has to be based on measurements, and testing, and experimentation, and hey- just the same thing you go through when making design decisions like whether to write C++ or assembly, and which kind of C++, and how to decompose the problem, etc, etc.
Sometimes these techniques will be appropriate, and sometimes they won't. Don't blindly condemn them all. Take a look at some of the examples where the template code produces the same assembly as the done-by-hand code.
If you're using a compiler which will develop templates in-line, decide if-statements at compile time, and discard unreachable code (which includes most modern compilers), it's better to write code which works that way, rather than use template specialization.
(Until, of course, you need to do it all with more than one type at a time, then it's back to copy-and-pasting everywhere.)
You assert that it's "better" to do it your way. Do you have numbers to back this up, or is it just your opinion? (It's okay if it's an opinion, I was just curious and wanted to check.)
-
Another marginal C++ featureThere's a group of C++ programmers who are into abusing the template mechanism into a compile-time programming environment. This is not a good thing.
The most impressive perversion of this ilk is the Blitz numeric library. This does loop unrolling by using the template library as a term-rewriting system. The resulting code is very complex, hard to debug, and of marginal value. Blindly unrollilng loops without understanding the target architecture at the instruction level is a lose on many modern superscalar machines. Newer machines tend to do loops faster than straight-line code.
Debugging compile-time processing in C++ is tough. You can't step through the process, you can't print anything, and the compiler doesn't provides any output about what's going on. Programming at compile time has a long, sordid history (LISP macros come to mind), and C++ is an inferior environment for it anyway.
If you're using a compiler which will develop templates in-line, decide if-statements at compile time, and discard unreachable code (which includes most modern compilers), it's better to write code which works that way, rather than use template specialization.
-
Blitz++
Another alternative to Fortran is C++ with Blitz++. Using templates, library builders are able to close the gap with or surpass Fortran speeds. And that is without any compiler optimization, which C++ recieves a lot of attention on because of its market status. Anyway, here is Blitz++. Here are their goals and philosophy. Eat your hearts out, C programmers.
-
Blitz++
Another alternative to Fortran is C++ with Blitz++. Using templates, library builders are able to close the gap with or surpass Fortran speeds. And that is without any compiler optimization, which C++ recieves a lot of attention on because of its market status. Anyway, here is Blitz++. Here are their goals and philosophy. Eat your hearts out, C programmers.
-
Re:C++ badYou know, sometimes that abstraction serves a purpose. Consider a library like FADBAD++ that allows you to differentiate C++ functions for use in problems like numerical optimization. I'd like to see you implement that code in C. The C++ solution is shorter, more elegant, easier to maintain and very easy to use. In fact, for numerical work in general, generic programming in C++ is an incredibly powerful tool allowing you to achieve the performance of FORTRAN with the conciseness and readability of normal mathematical notation. Blitz++ is a good example too.
I find that the people who advocate C over C++ have really done nothing but use C++ as a glorified C. Even the people who claim that they are using C++ properly with high falutin' OO methodologies are still writing code that can be transformed into C with a minimum of effort. Code written generically with C++ templates cannot trivially (in a precisely definable sense) be transformed into C code and hence can be used to efficiently solve problems that are a nightmare in C.
-
Re:hehe.. sorta
Another problem I have with C++ is that even with all its power you have no way to get to the "left hand" variable of operations. For example, if you have a matrix class you can overload the "+" operator so that you can do things like "matrix3 = matrix1 + matrix2". However, that's not going to be very efficient (assuming that's why you're using C++ in the first place) because there is no way to get to the matrix3 variable from inside the + operator. That forces you to use a temporary variable to add the two matrices then copy by value the whole matrix after adding matrix1 and matrix2. There are tricks around this problem but none are clean.
You might want to check out expression templates. This is an advanced technique that addresses exactly your problem. With this technique, you can do stuff like this:
A = B + C - D * E / J;
... and this will get translated to:
for (i = 0;
...) {
for (j = 0; ...) {
A[i,j] = B[i,j] + C[i,j] - D[i,j] * E[i,j] / J[i,j];
}
}The Blitz++ library is the foremost library that uses expression templates. Check it out! There are ways around C++'s shortcomings...
-
Re:hehe.. sorta
See Blitz++. Its amazing what one can do with turing complete templates.
-
It's great to see some metaprogramming related......proposals. Without metaprogramming C++ really is glorified C. But with metaprogramming C++ becomes an entirely new system. The template system is computationally complete (see here for what that means) and so important work can be shifted to compile time. That doesn't just mean computing the answer at compile time, that would be silly. It means procedurally building and optimizing code. For example we all know that C is slower than FORTRAN because pointers (lacking in FORTRAN) bring in variable aliasing problems that stop the compilers reliably optimizing. C++ metaprogramming allows us to claw back some of that loss by intelligently building optimized math routines at compile time. See Blitz++ for examples. The net effect is the speed of Fortran combined with readable high level references to array and vector objects.
Unfortunately metaprogramming is a pain in C++. One of the biggest problems is the lack of reflection in C++ that would allow template metaprograms to easily determine type information. Some of the new proposals would remedy that issue. Also the use of local classes in templates, that is sorely lacking in the current standard, would be a great boon for such techniques.
And maybe one day there will be many more C++ textbooks that don't just relegate templates to half a paragraph in the "advanced techniques" section. Templates are fundamental to C++. If you don't use the benefits of C++ then C++ really isn't that interesting a language. No wonder so many people propose using C rather than C++. It's like programming in Lisp but refusing to use list datastructures.
-
Compile-time matrix multiply in C++.It's been done. Download the Blitz matrix library for C++ and realize the true power of templates to cloud the mind. By using templates as rewrite rules, fixed-size matrix multiplies can be generated inline at compile time. The concept is general and can be extended to arbitrary matrix operations.
Now that it's been shown to be possible, it's generally considered to be a bad idea. Since superscalar machines came in, loop unrolling can be a lose. Today, branches in tight loops are cheap or free by the second time around, since the branch predictor knows what happened last time. You get more cache misses with bloated code, too. Loop unrolling isn't the big win it used to be.
-
Re:BloatI was actually going to bring up Blitz++ as well . . . as an example of when templates are both remarkably useful and mind-bendingly obscure.
I'm not a language designer, but it seems to me that what is needed is some kind of a compromise or hybrid between the intended Java approach to templates/generics and the C++ approach.
If memory serves, Java templates are going to be implemented by erasure, a la GJ. The point behind this is that Java needs bytecode backwards compatibility, so it can't adopt parametric types into the runtime language.
Basically, the compiler will use generics to figure out whether or not operations are guaranteed type-safe and then do the casting for you. (Not sure if it's bright enough to pull off making the cast cheap once it's known to be safe; also not sure if this is safe during reflection. Check out this comment and the discussion surrounding it for more.)
Anyway, if erasure can be made cheap (i.e., without the cost of <dynamic_cast>) then doing (at least basic) templates with erasure could resovle some of the issues with #define templatizing. So you could leave the truly hairy stuff with C++ style templates and simple collection manipulation with erasure-templates.
Now I'll wait for someone to tell me why this is a horrible idea.
-
Re:Numbers of some Interest. Conclusions a yawn.
A very large part of clsoing the gap should be attributed to C++. It's a younger language, which means it's development is progressing faster. Both C++ and Fortran are probably approaching the theoretical maximum speed asymptotically, with a few years lead for Fortran. A extensive resource can be found here
-
Yeeeeeeeees
But sometimes the terse name is the right one to use. The standard examples come from maths programming. If you have a Complex number class, then it is far more natural to write
Complex c1;
Int i;
Complex c2 = c1 + i;
Rather than
Complex c2 = c1;
c2.addInt(i);
Of course a method is usually the best place to put functionality. But not always Blitz is a great maths library using templates and operator overloading when necessary to produce a very powerful and usable system.
Other examples are the iostream library and STL in C++.
The ability to overload the <operator allows the STL to use primitive types and user defined types in the same algorithms. -
Re:What is Fortran used for these days?
Blitz's benchmarks show that Fortran isn't quite the speed king you imply it is. As they show Blitz++ does more aggressive loop unrolling than Fortran. The main performance bottleneck seems to be that Blitz++ doesn't do loop jamming, although they show there are circumstances in which loop jamming makes the Fortran compilers slower. The moral of the story: benchmark, never assume.
Fortran may be faster for your particular application. But it may be slower. If performance is that important then you have to write both and benchmark them. If performance isn't that important then other considerations (availability of libraries) dominate. -
Why not learn them all...Let me preface the following statements by stating that I program in C/C++/Fortran within a high performance computing environment.
There are many, many numerical based libraries available (see LAPACK, BLAS, SPARSEKIT, etc) that were originally written in Fortran. Many people much smarter than I have spent countless hours writing, optimizing and verifying these libraries. Since there is no point in reinventing the wheel, I make heavy use of the above.
However, just because they are written in Fortran doesn't mean I have to write in Fortran. I can link in these libraries using whatever language I chose. In my case, that's C/C++.
The advantage and disadvantage of C/C++ is that they are advanced languages. You are given more than enough rope to hang yourself multiple times. At the same time you can write some amazingly powerful stuff. Good style and experience can protect you from many pitfalls.
You mention that you find you are spending too much time fixing bugs related to your lack of experience with C++. If you are more experienced in Fortran than C++, then certainly you may find your time better spent coding in Fortran.
However, there is no evidence to believe that Fortran is a superior numerical coding language based solely upon the large available base of libraries. Packages such as Blitz++ written in C++ have already demonstarted performance on par with Fortran based codes.
If you have the freedom of choice use whatever you are most comfortable in using. The reason Fortran numerical libraries are still around is sheer inertia. Personally I can't imagine coding in a language as full of vestigial punchcard idiosyncrasies as Fortran on a daily basis.
-
Blitz++
Blitz++ makes use of C++ templates to deliver near FORTRAN like speeds (and in some cases better).
Don't be afraid of C++ templates - all this Blitz code stays clear of C++'s pointers, and are very easy to use. -
Re:Use Fortran 90
Not true when compared against modern C++ (and its compilers). C's libraries may not be (and may never be due to compiler pointer aliasing issues), but C++'s are. One in particular is Blitz++.
Not to take away from Fortran. Language in general means far less to performance than an experienced programmer and good algorithms. A good compiler helps too. After that, it's all ones and zeros -- not a language that most humans can understand. -
Don't use Fortran 90.Don't use Fortran 90. It's as messy a language as C++, with the significant disadvantage that it has a much smaller user base.
Honestly, your objection to C++ is unclear to me...you say you spend more time fixing bugs than approaching the task at hand? Is this because you don't know the language that well? Perhaps because you're not taking advantage of the many excellent libraries available to you? Keep in mind that C++ library design requires a great deal of skill, but using a well-designed library is actually easier than coding in other languages.
C++ is my own personal choice for anything by the most demanding of high-performance computing applications. Is there an overhead to the language? Debatably, yes. Does it matter, in 99.9% of applications? No. And with only a little bit of forethought, even the "inherent" performance hits can be avoided in the places where it matters. It's just that you have to rely on a profiler to tell you where those places are...
There is a significant community of researchers and developers working on scientific and high-performance computing in C++. Check out some of these:
- POOMA - a high-performance mathematics C++ framework
- Blitz++ - a C++ mathematics library which uses template metaprogramming to achieve FORTRAN-caliber performance.
- MTL - another example of template metaprogramming.
- oonumerics.org - a good site for information on high-performance object-oriented code.
These are just a few good starting points. Do a google search for 'high performance c++' to find many more. Just, please, for the love of Deity, don't code in FORTRAN. ick....
-
Don't use Fortran 90.Don't use Fortran 90. It's as messy a language as C++, with the significant disadvantage that it has a much smaller user base.
Honestly, your objection to C++ is unclear to me...you say you spend more time fixing bugs than approaching the task at hand? Is this because you don't know the language that well? Perhaps because you're not taking advantage of the many excellent libraries available to you? Keep in mind that C++ library design requires a great deal of skill, but using a well-designed library is actually easier than coding in other languages.
C++ is my own personal choice for anything by the most demanding of high-performance computing applications. Is there an overhead to the language? Debatably, yes. Does it matter, in 99.9% of applications? No. And with only a little bit of forethought, even the "inherent" performance hits can be avoided in the places where it matters. It's just that you have to rely on a profiler to tell you where those places are...
There is a significant community of researchers and developers working on scientific and high-performance computing in C++. Check out some of these:
- POOMA - a high-performance mathematics C++ framework
- Blitz++ - a C++ mathematics library which uses template metaprogramming to achieve FORTRAN-caliber performance.
- MTL - another example of template metaprogramming.
- oonumerics.org - a good site for information on high-performance object-oriented code.
These are just a few good starting points. Do a google search for 'high performance c++' to find many more. Just, please, for the love of Deity, don't code in FORTRAN. ick....
-
Re:of course it's still kicking
C's libraries may not be (and may never be due to compiler pointer aliasing issues), but C++'s are. One in particular is Blitz++.
Not to take away from Fortran. Language in general means far less to performance than an experienced programmer and good algorithms. -
Re:This has all been hashed out many times
Look at the Boost++ library as an example of using C++ to get levels of numerical performance near to Fortran--which was almost impossible with plain C.
Either you're confused or had a temporary brain-fart. Boost is a library of classes, algorithms, and other features that, in a general consensus, developers feel should be added to the standard C++ library. Blitz++ is a numerical computing library based heavily on C++ template expressions and specialization. -
Re:Downsides
Itanium chips could do extremely well on many of the STL algorithms. (I have wondered if the Intel Optimizing compiler for Itanium would do massivly parallel ops with valarray classes. Does anyone have experience there?)
I'm not aware of any compilers, for IA-64 or for any other arthitecture, that do special things with std::valarray. My impression is that the people who care about high-performance matrix computation in C++ are spending more effort on things like MTL and Blitz than on valarray.
It's a pity, in a way. The C++ standard was deliberately changed, in subtle but important ways, to allow implementers to do clever optimizations with valarray. But if any implementers have taken advantage of that freedom, I haven't heard about it (and I'm in touch with enough people so that I probably would have).
-
Re:Not all compilers support it, god-awful comp erTo say that the preprocessor is equivalent to the C++ template engine is...well...wrong.
:) There's a lot more to templates than type-safe inline functions (which are nice, to be sure).The great power of the template engine is specialization and pattern matching. This allows compile-time functional programming, known as template metaprogramming. Metaprogramming provides all sorts of cool possibilities, including program generation, type-safe, compiler-aware conditional compilation, blazingly fast numerical computation and embedded domain-specific languages. For examples of the latter two, check out Blitz++ and Spirit, respectively.
-
Re:Sparse matrices?
-
What speed hit?Last time I checked people were writing faster readable code in C++ than in C.
A smart C++ programmer can use template metaprogramming in a library like Blitz++ to automatically build code optimised for the job. To write the equivalent code in C is possible but it's much more laborious and harder to maintain.
There are good reasons not to use C++. Performance isn't one of them. -
What speed hit?Last time I checked people were writing faster readable code in C++ than in C.
A smart C++ programmer can use template metaprogramming in a library like Blitz++ to automatically build code optimised for the job. To write the equivalent code in C is possible but it's much more laborious and harder to maintain.
There are good reasons not to use C++. Performance isn't one of them. -
Re:There are other excellent compilers
It is worth noting though that GCC version 3 is one of the most standards-conforming C++ compilers available.
It is significantly better than Intel's on weird template and STL stuff, and a vast improvement over Microsoft's Visual C++ (which even in its latest incarnation has failed to address partial specialisation bugs dating back to vanilla 6.0.) Just because these template issues are weird, does not make them useless. On the contrary, they can allow code which is both more easily maintained and faster. For examples, consider Blitz (templated numerics library) and Boost (a very well thought out set of extensions to the standard C++ library.)