Domain: oonumerics.org
Stories and comments across the archive that link to oonumerics.org.
Comments · 67
-
C++, efficiency, and OOI feel like clearing the air of half-baked comments and know-nothing OO detractors.
First of all, for those individuals who refer to C++ as an OO language, please stop. You're wrong. C++ can be used for an OO project, but it is a multi-paradigm language. At least that's what Bjarne Stroustrup calls it. But what does he know about C++?
Second, use of C++'s STL does not equate to OO programming. It is an example of generic programming. Here's a hint: the STL has very little inheritance except for iterators and iostreams -- most evaluation is handled at compile-time. And even iterators and iostreams are just as much generic as OO.
Finally, please dispel the rumor that C is automatically faster than C++ because of C++'s excessive overhead. Need proof? Please read this article about treating C++ as its own language and not a variation of C. Yes, it's a PDF. Get over it.
Think the article is FUD? Prove it! Take the examples from the article and tune them better than he did. Compile them with trusty ol' gcc and g++ on your box. Measure the results. After you do so, can show that C is faster, does not contain any potential buffer-overflow bugs, handles error conditions, and wasn't at least five times more code to do it, then reply back with your results. I have a feeling I won't be getting any replies from people who actually try it.
That said, use whatever language you like best. Studies have shown that people will always perform better in languages they know intimately well than languages in which they have a general familiarity.
But if you want to use OO and C++, check out this numeric library
Have a nice day
-
OO Numerics is a research topic
The short answer to your question is yes, OO techniques can be used to build better engineering (i.e. numeric) codes.
The longer answer is that applying OO techniques have been adopted very slowly by the numeric computing community because there are some difficult problems in marrying the two that are still being actively researched.
A very good resource for OO numerical computing is here -
Can be faster
There are many instances where C++ can actually produce faster code.
For a simple example, compare the C qsort with a C++ template Quicksort function. In the C++ version, the comparison operator would likely be compiled inline to the function, meaning that you don't get the overhead of a function call for every comparison. In C the only way you could do this would to be to write quicksort yourself for every data type that needs it. C++ templates allow a lot of work to be done at compile time, rather than at runtime.
Check out http://www.oonumerics.org/blitz/ for fast C++ scientific applications.
cheers,
Tim -
OOPs (I did it again)
Take a look at BLITZ++, then tell me OOP is not useful for scientists and engineers.
:-)
I think the safest thing to say is that whatever your programming needs, whether you're doing pure matrix/BLAS number crunching or writing complex simulations/models, you should think twice before using FORTRAN. Well-written code in, say, C++ will be more maintainable and accessible to other people you work with (and who have to touch your code in future).
The only thing which keeps people using FORTAN that I've seen is that the optimising compiler support is fantastic compared with the equivalent offerings in C/C++ compilers. But that's not much of an excuse for general day to day problem-solving.
Just my 2p. -
Re:Before the flame wars start...
-
Not object-orientedAlthough this accomplishment is very impressive, I'm just wondering if GSL is better than fortran libraries.
I'd like to use a library with object-oriented design like those in OON. Since GSL is written in C, it would not help object-oriented programming style.
-
Re:Java lacks genericity...
It's almost the complete opposite, actually. For a start, the myth that templates cause code bloat is falling apart.
Perhaps more importantly, much state-of-the-art research in C++ relates to good use of templates. Some very powerful techniques, particularly relating to efficient and flexible library design, have come from templates. Check out the Blitz++ and Loki libraries for examples.
-
Re:C++ not useful for numerical computingC++ isn't horrible for numerical computing, it's just harder to do it right in C++. If you're writing a specialized numerical integrator, so solve a highly tuned set of fluid equations for example, you're probably better off with Fortran. However, if you need a toolkit to perform research and analysis C++ can be wonderful. I speak from experience. I've spent the last 3 months extending the blitz++ library. I've built a very powerful toolkit for analyzing enormous data sets. I slice, dice, chop, rearrange, transform, and abuse my data. The memory management is rock solid. The code is fast (admittedly not as fast as some C prototyping that we've done, but close), and the whole OO paradigm has worked very well. Yes, C++ is not useful for quick one off numeric solutions, but it is great for building extensible research toolkits if you take the time to think your solution out and do it right.
To get back on topic, I use Ruby too. I've built parsers to analyze code and automate some very hairy analysis tasks. We've written patents and sold projects with Ruby code. I think that Python would next best language that I could have done that work with, but I felt that Ruby gave me much more freedom.
-
Re:Turing equivalence?The Template Metaprogramming mentioned in other posts illustrate the power of templates. While there may not be a facility for looping in the "linear iterative process" (see "Structure and Interpretation of Computer Programs for a definition) sense, there is in the "linear recursive process" sense. What happens is the proprocessor expands the templates. If a template has a template as a parameter, the embedded template is also expanded. This continues until an atomic (terminating) parameter is passed or until the preprocessor runs out of steam. Of course, for this to work on compilers like gcc, you need to increase the -ftemplate-depth-xx to obscene values. Since the preprocessor expands the code into new, legal, C++ code, you can write very fast loops. This is because the loop is unrolled, and you have explicit code (that the preprocessor wrote from your instructions) that usually smokes its competitors. Now for the obligatory link: Go to the Blitz++ web page to see a nice example (and some interesting papers on the subject).
The thing I find amusing about this is that languages like Lisp provide this exact functionality without the truly cryptic syntax (although you could argue that parentheses are replaced by angle brackets).
-
Re:Define a problem domain for your language
Except for FORTRAN, which still kicks C's ass on numerical applications because of the "pointer problem", and yes C++ can produce code as fast as C, but it's much more difficult due to the complexity of the language.
Standard C++ fixes some of the performance problems with earlier implementations. For an eye-opener, check out Blitz++, a numerical library written in C++. It performs on par with FORTRAN, sometimes even exceeding FORTRAN's vaunted numerical speed.
Standard C++ can also be much, much faster than C. The standard sorting algorithm is a typical example. std::sort is 250% to 1000% faster than qsort according to one benchmark. It is 20% to 50% faster than a hand-coded C quicksort for a particular data type. I have seen such results elsewhere -- this is just the first page Google turned up.
Yes, std::sort is using inlining to good advantage. That's not "cheating" as some may argue. C++ (and the standard library) provide the efficiency of inlining while maintaining genericity and separation. That's what templates do. It's an intrinsic part of the language. C++ and the standard library help you reduce programmer time (less code to write) and execution time in many important cases.
C++'s combination of static typing, polymorphism and generic programming while maintaining the ability to do "traditional" C-style structured programming is really, really nice. I have my choice of options for coding particular modules and I don't need to learn three different languages to do so. One could even argue that C++ supports a fourth model: with template metaprogramming, one can write C++ code in a style that almost looks like functional programming in the sense that recursion is used exclusively and the code implements functions that do not modify any values. Granted, this form of coding is limited to compile-time values, but it can be used in lots of surprising ways to do things like generate entire class heirarchies automatically.
--
-
Re:OCaml (Re:What I'd like to see.)
I repeat, C and C++ should have identical performance for most tasks, because they should produce identical output code for those tasks. If you are seeing otherwise, get a better C++ compiler. The idea that C++ should somehow produce inferior performance is a myth perpetuated by ill-informed C++ naysayers.
This claim is not based on any one benchmark or a little personal experience, it's based on an intimate knowledge of both languages, and their respective compilers and implementation details. I also work in scientific computing, and happily use C++ in favour of C. If you want to see how effective C++ can really be, try looking at Blitz++ for example.
By all means make sensible comments about OCaml, but please don't spread ill-founded rumours.
-
sighI like the current C++ standard. It is very expressive and powerful. Just look at the amazing things that have been developed using templates, like the Blitz++ library . Having said that, it's very frustrating to have so many compilers (read, none that I know of) that support the entire standard. By doing this, Stroutrup et. al. are simple going to create a new divide for vendors (including the FSF ) to play catchup with.
Their goals of avoiding stagnation and fossilisation are admirable, but as an active developer (and student) of C++, I find this to be counterproductive. Thinking about new constructs and definitions is always a good goal; redefining the standard that can hardly be considered standard if divisive and stupid.
Just my $0.02.
-
Maybe /.ers have an opinion then?These other questions were so great I didn't make the cut but maybe you folks have opinions you'd like to share?
What do you think of template meta programming? Do you consider it a boon, enabling clever programmers to do outrageously cool things like the Blitz project? Or is any benefit derived from it's use washed away by the obscure, nearly unreadable code it takes to implement it?
-
Re:Metaobject Protocol for C++
I hate the name "Metaobject Protocall" (MOP). It sounds academic - not something that a working programmer would ever make use of. I would like to (briefly) describe what a MOP is and why it is useful.
A MOP opens up a compiler in controlled ways. You define call-back functions that will be called when the compiler recognizes certain constructs - like defining a member function, assigning to a class, or using a class in an expression (like vector a+b). There will also be ways of finding and changing a class's members and base classes. The way you define these callbacks, is through metaclasses. It's easy, but not really that important for this brief introduction (see OpenC++). A not-so-bad way to think of a MOP is as the builder pattern.
That's the mile high view. Now, what can we do with it.
- Before/after methods. Originally, Stroustrup had before/after methods in C++ (he took them out after he found he was the only one making use of them). Before/after methods could be defined for functions so when the function was called its before method would be called first, and when the method returned, its after method would be called. This was useful for locking and unlocking semaphores (for example). Now, with a MOP, this is easy to implement. Everytime a method is called, we can use our hook into the compiler to insert a call to our before method and after method.
- Delegation. The decorator pattern uses delegation as its implementation. Consider a graphics class hierarchy: class Graphic; class GraphicDecorator : public Graphic. GraphicDecorator has a data member of type Graphic*. It needs to forward all of its function call to its contained graphic. This is straight-forward, but error prone. If we add a new function to Graphic, we need to remember to add it to GraphicDecorator as well. With a MOP, we can automatically build an class that delegates its function calls.
- Mulidispatch. I built code that does double-dispatch for C++ (for the visitor pattern). The implementation to make the function call was pretty straight forward: some tables of pointers to members that are indexed by the parameters (a virtual function call on the parameters to get the correct index). While the code to make the call was easy, building the tables was not. To build the tables, I needed to know and the inheritance tree. While the compiler knew this, I couldn't get at it. So I had to build code to automatically create this information at "static initialization" time (I don't know the correct term). This was especially challenging because of static initialization ordering problems. With a MOP I can directly access the inheritance tree. I don't have to build it myself. As a side note, Stroustrup did consider putting multidispatch into C++, but decided against it because it required too complex a linker.
- Optimizing vector/matrix classes. If you know about metatemplate programming (see blitz), you know you have to write some very complex code to optimize linear algebra code. With a MOP, you can use the hook to translate expressions to do these optimizations much more sanely.
- Object persistence. If you want to use pointer swizzling to implement object persistence, you need to know where the pointers are on a given page. With a MOP, you can find the layout of an object and keep track of where the pointers are on a memory page.
- Writing browsers.
- Writing "bridge" code to interface C++ with other languages, like Python.
I hope this gives you a taste of why I'm excited about MOPs. I haven't written much code using MOPs (I certainly don't claim to be an expert), and I'm not sure its ready for prime time yet, but I'd love to hear Stroustrup's view on this.
-Scott - Before/after methods. Originally, Stroustrup had before/after methods in C++ (he took them out after he found he was the only one making use of them). Before/after methods could be defined for functions so when the function was called its before method would be called first, and when the method returned, its after method would be called. This was useful for locking and unlocking semaphores (for example). Now, with a MOP, this is easy to implement. Everytime a method is called, we can use our hook into the compiler to insert a call to our before method and after method.
-
What do you think of TMP?
What do you think of template meta programming? Do you consider it a boon, enabling clever programmers to do outrageously cool things like the Blitz project? Or is any benefit derived from it's use washed away by the obscure, nearly unreadable code it takes to implement it?
-
Template metaprogramming
Modern C++ compilers have great power via `template metaprogramming'. Using partial template specialisation we can practically write our own compilers that build on the C++ compiler. See for example the blitz++ linear algebra library or my own compile-time primality tester. Unfortunately these techniques are very unwieldy even though they can have have a great payoff for high performance computing. How do you see template metaprogramming evolving in the future and how could C++ be modified to accomodate it better?
-
Backgrounder: A=B+C for all types
What a great article! There's a lot to get through there, so I thought I'd add a bit of extra info about one bit I know well.
Tim mentions how much more clear it is to use direct assignment (A=B+C) for all types (including lists) than having to worry about the details of the specific classes. This issue is part of the study of generic programming. This is generally quite easy to do with functional languages (e.g. have a look at some Mathematica programs to see what I mean).
A lot of effort is going into making this available in C++, with a particularly success being achieved by the STL. The STL gets over the problem of speed through using templates, which (as Tim mentions) are dealt with at compile time rather than run time. Although Tim apparently has no time for templates, they certainly achieve good results in the STL.
Those of you with their thinking hats on will be wondering "but what happens if I write A=B+C+D?". The STL would create two loops and two memory copies, since it thinks of it as ((B+C)+D). Some very interesting work to avoid this problem is being implemented in class libraries such as POOMA and Blitz++ which implement the fiendishly clever concept of expression templates to actually create and traverse a parse tree of the expression at compile time. Of course, this can lead to very long compilation times. An amazing side effect of this approach is that if you never actually use a value in A (having assigned B+C to it), then it will never get evaluated (e.g. the classes use 'lazy evaluation').
If you're interested in trying out some of these ideas in a strongly typed language, it's worth looking at C++. You'll need a good compiler though--if you're using GCC make sure it's the latest version, or for better results still try KAI C++. If you're a complete newcomer try out a functional language--I particularly recommend Mathematica, although you can use the functional concepts in Python (e.g. Map()) and Perl to make a start.