Domain: gotw.ca
Stories and comments across the archive that link to gotw.ca.
Comments · 86
-
GotW #50: vector is not a container
Alex: I regard my first encounter with the STL (very shortly after its first public release) as one of the great eye-opening moments in my software development career. Unfortunately, as I'm sure you well know, quality of implementation issues in compiler support for the C++ template idiom cultified (i.e. made cult-like) the deeper principles for at least five (if not ten) years thereafter.
I've long regarded the criticism against vector[bool]—I'm not going to fugger with angle brace entitiesâ"not being a container were misguided. Of course, it *must* be a container for reasons of sanity, but to portray the problem as a standardization committee brain fart seems to miss the main point.
Just as STL introduced a hierarchy of iterator potency (that was the main technical innovation behind the STL, was it not?) one could likewise introduce a hierarchy of container potency. The container we ended up returns interators which promise a dereference operator returning an lvalue (it's been a long time since I've used this terminology) which is why the following statement from the linked discussed is expected to work:
typename T::value_type* p2 = &*t.begin();But actually, of all the uses of containers found in the wild, I highly doubt that more than a small percentage (potentially a very small percentage) exploit the property that interator dereference returns an lvalue rather than an rvalue.
The net effect is that the standard containers promise us a potency we rarely exploit, yet the burden of this potency is universal. Forsake it in even the smallest way, and you'll be shouted out of the room for non-containerhood.
We could have handled vector[bool] by changing the standard container to not promise IDLV (container iterators dereference to lvalue). In cases where the programmer goes ahead and tries to do this, he or she obtains a simple syntax error (ha ha ha) and knows to either reformulate the algorithm to not require this property or to go back and add a specification override to the container setting the IDVL property to true.
With IDVL set, vector[bool] does not specialize.
With IDVL unset, vector[bool] will specialize.
Problem solved, except for the language overhead of introducing (and managing) a container strength hierarchy.
But instead, Herb Sutter decides to write this:
Besides, it's mostly redundant: std::bitset was designed for this kind of thing.
Doesn't that attitude make you want to pound your head upon a table somewhere? Seriously, if one repeats that remark 1000 times, we could almost make the entire STL go away (and return to the world we would have had instead had the STL not rescued us from parsimony mass produced.)
Clearly, there was enough of a pain point in the C++ standarization effort around iterators that the STL gained traction exceedingly quickly (and very late in the day), yet the C++ community is also extremely hidebound about minor pain points, as evidenced by Sutter's explanatory tack.
Obviously, there were some advantages in demonstrating that the STL approach could achieve performance comparable to C (and in some cases, better than C) in proving that the STL was not just another abstraction gained at the expense of runtime overhead (which all looks fine until five or ten different runtime overheads—however small each of these appears in isolation—begin to interact adversely).
But very quickly, the initial quality of implementation issues and the quirky (to be extremely kind) limitations of the C++ template mechanisms threw up some major walls in pursuing the underlying ideas behind the STL more extensively.
So, my question is this, more or less: in retrospect, was the early victory with C++ worth it (it's extremely easy to understimate the value of having a good idea noticed at all), or does the eternal puberty of the C++ STL continue to grate?
-
Re:Very much so!
Gosling did it, as did Ritchie. in a panel conversation along with Stroustrup. That covers all the majors. So how many other big language creators do you know that haven't said something similar?
Not particularly, because I don't really use them much. And how hard is a lookup routine anyways? (Even mail is mostly lookup with a minor backend that I personally have written at least 4 times - ie, even I can do it:) The rest is adserving (blocked significantly, apparently) and tracking, and other things that don't really affect the general user's services.
-
Re:Long overdue
Kernighan and Ritchie were well aware of Turing completeness. Dennis Ritchie started with Theoretical Computer Science before he wrote his first software (see http://www.gotw.ca/publications/c_family_interview.htm). You can be sure that designing C without Turing Completeness would have been for them like designing a car without tires.
Languages without Turing Completeness only make sense only in special applications because they are so limited (e.g. the C PreProcessor is not Turing Complete unless you use it recursively).
One of the marvels of the Turing machine is that it is so simple (you can describe what a Turing machine does on 2-3 pages) but it is as powefull in expression as modern languages with specification of thousands of pages are.
A lot of coders have no idea about the theories behind it. That is why a lot of code sucks. It's not the lack of Turing machines but on the theories that are connected to it (e.g automata theory, complexity theory).
What you are saying is like: I am tiler, i never check the foundation when i am building the roof, so it can't be important
;-).You can make a living as a coder without all that knowledge. More than half of the coders do. But if you look at the people who shape the world of software (like Dennis Ritchie, Linus Torvalds, James Gosling, etc), you will notice they all are well versed in the area of computer science theories.
P.S. Concerning AI and Turing Test: computer games have no AI. The producers of computer games call their software opponents AI, but they are a collection heuristical algorithms cobbled together.
When you are playing agains an opponent, you can usually tell easily wether this is a computer or not. In fact, you are conducting a Turing Test then and the other side fails usually miserably.
-
Herb Sutter called
He says to tell Qualcomm that free lunches are over.
-
Re:No point
As a long-time Java programmer who wants to learn/use C++, I'd love to hear your insights, so that I don't appear on your wall of shame.
:)In addition to the other replies, here are a few I have encountered:
- Don't overuse dynamic allocation. In Java, this is just "how you use objects". In C++, this is how you separate object lifetimes from the local scope. Most variables have scope-bounded lifetimes, so let the compiler do the work for you.
- Don't overuse dynamic polymorphism. All methods are effectively virtual in Java, which IMHO encourages unnecessary class hierarchies. Much high-level logic is not actually polymorphic, so your default approach should be avoidance.
- Don't overuse class inheritance. In many situations, aggregations are sufficient, but inheritance is so easy. For example, maybe in a multithreaded app, several key objects need to be locked for access. So they could either inherit from a parent "mutex" class, or they could contain said mutex as a member. The latter should be preferred—even if it requires some inline forwarding-functions—as it more accurately describes ownership to maintenance developers: the mutex belongs to the business object. The BO isn't itself some sub-type of mutex.
- Don't use classes as namespaces. If a class is full of static methods and you never actually instantiate the class, then it's a namespace in disguise.
- In interface code, prefer forward-declarations of dependencies to #includes. It really helps to keep dependency management under control, which matters due to the nature of the C preprocessor.
- Capitalize upon the separation of interface (*.h) and implementation (*.cpp). Since Java uses a single file, it may seem very cumbersome to have to re-declare function signatures and such. However, the benefit is that the implementation can internally #include private utility headers which are completely invisible to downstream developers. Or the implementation can directly contain static global functions and data, again entirely invisible downstream.
- If your codebase uses exceptions, learn about exception safety and try to refactor away try blocks. Intermediate layers which catch and then re-throw exceptions are often easier to manage when using RAII "guard" objects to handle exceptional cleanup. Your code can become transactional, with a nonthrowing commit at the end if everything succeeds; or an implicit rollback if any exception is thrown.
-
Re:Problem with Exceptions
... writing five exception handlers
...If you think every caller should have logic which reacts to errors, why do you need automatic stack unwinding? Just use error codes.
Not being thorough is bad always engineering.
But catching exceptions—only to re-throw them—is not "being thorough". It is boilerplate. If the caller is not exception-safe then you should consider a more transactional paradigm, so that you don't need to catch and re-throw. If you want to force callers to handle errors immediately, then stop using exceptions and start using "checked error codes" (i.e. lightweight objects which represent error codes and verify that the caller has acknowledged the error state).
-
Re:Agreed.
It's better than C++ where you cast a pointer and the code happily treats random gibberish as the type you cast to.
Funny that you mention C++ instead of C for this argument. In C, pretty much all you can do is cast the pointer and cross your fingers. In C++, you can correctly handle run-time polymorphism with dynamic_cast (or just use a virtual function to begin with, dynamic casting is usually a code-smell); or you can handle compile-time polymorphism with templates which rely on more-or-less the same duck typing that Python does. The compile-time polymorphism is admittedly much hairier (cryptic syntax, potential surprises from ADL/Koenig lookup, and some nastiness with function overloading vs. template specialization), but your characterization of C++ sounds like a straw man borne out of some unnecessarily bad programming experience.
-
Re:Agreed.
It's better than C++ where you cast a pointer and the code happily treats random gibberish as the type you cast to.
Funny that you mention C++ instead of C for this argument. In C, pretty much all you can do is cast the pointer and cross your fingers. In C++, you can correctly handle run-time polymorphism with dynamic_cast (or just use a virtual function to begin with, dynamic casting is usually a code-smell); or you can handle compile-time polymorphism with templates which rely on more-or-less the same duck typing that Python does. The compile-time polymorphism is admittedly much hairier (cryptic syntax, potential surprises from ADL/Koenig lookup, and some nastiness with function overloading vs. template specialization), but your characterization of C++ sounds like a straw man borne out of some unnecessarily bad programming experience.
-
Re:But...
-
sorry - REAL link with gosling here.
sorry wrong link from another story: Here is the real link: real gosling link
-
Re:The kernel
For instance, when the stream gets an indication that the TCP connection was disconnected, they could perhaps try to re-establish the connection, but if that doesn't work it should throw the DisconnectedException it got up to their caller until either something either fixes the problem or the application crashes.
Please humor my pedantry, but perhaps this is a bad example. A TCP connection is a stream, so any other stream based on a TCP connection is not at the appropriate abstraction level to catch anything. If it's an HTTP connection (with an in-flight GET request that may have been lost), let that layer handle restarting the stream and re-issuing the request. If it's a lossey stream of video data, let that layer restart the stream, wait for the next keyframe to show up in the input, and resume sending new data. I regularly see people writing "adapter" layers such as a TCP iostream wrapper and trying to handle exceptions when it is wholly inappropriate to do so—they should simply guarantee some level of exception safety and then get out.
What you want to do in an exception handler is fix what you can, and throw up the call chain what you can't.
IMHO, what you really want to do is replace the exception handler with a RAII "guard" object that will perform cleanup in its destructor if
.commit() has not been called. This gives you all of the benefits of a try/catch block without forcing the try/catch on your parents. Keep in mind that if an exception is thrown with no outer try block, the program may omit stack unwinding and abort with a nice healthy core dump. If a single "middleware" layer inserted a try/catch block with a re-throw, then your stack trace shows up in the middleware's (usually useless) function and the source of the std::out_of_range remains a mystery. (note: this is probably undefined behavior, but it is damn nice and worth leveraging.) -
Re:I looked at .NET briefly
Apparently, you can't safely store an auto_ptr in a collection. That is a pretty common situation. While auto_ptrs are pretty sweet, and by that I mean totally cool, they are not a panacea.
http://www.gotw.ca/publications/using_auto_ptr_effectively.htm
-
Re:Number of components, not computing power
Moore's law is dead in everything except transistor count.
Here's the picture I was looking for, smack in the middle of:
http://www.gotw.ca/publications/concurrency-ddj.htmAbove 4Ghz, the power loss due to transistor current leakage suddenly starts going way up and becomes the most significant term.
It will take a fundamental change in the way we build transistors to get any kind of efficiency above 4Ghz... maybe photonic or micromechanical gates.
-
Re:The wall, and the end of the world.
There are notable counterexamples. For example, CPU clock speeds have been approaching a limit for years now. The only reason computers get "faster" over time is Moore's Law, which allows the CPU to do more per clock.
http://www.gotw.ca/publications/concurrency-ddj.htm -
Re:thus a disaster
You'll see exceptions, then memory leaks, an attempt to solve it with some kind of braindead "smart" pointer, somebody needs multiple inheritance, some ass overloads the comma operator or () operator, overloading gets sort of ambiguous with differences between the 32-bit and 64-bit builds, Boost gets pulled in with compile times and start-up times going to Hell, people cry for Java-style garbage collection...
If the first thing you get from C++, coming from C, is exceptions, then you're going to be in a world of pain. Most people who started with C++ have trouble with it. For a quick indication why, see Code Complexity @ GOTW.ca
.As a 10-year veteran of C++, I say to start with RAII, and since you're going OO, require everyone involved to learn the SOLID principles.
-
Re:Blocks and GDC
I think 16 or 32 is counting low.
Consider Larrabee (yes, it is a GPU, but it runs the x86 instruction set, so it'll certainly not be long until it gets used by regular apps for other stuff as well), it is assumed that it will have 32 cores in its first version, and each will have four hardware threads. Presto, 128 hw threads! And this will likely be available in about a year!
How long until this sort of tech goes into the general cpus? I'd say less than 3 years.All developers worth their salt should start thinking about concurrency, and how they're going to make use of these multitudes of low-powered cores. I can recommend Herb Sutters course in "Effective Concurrency" for those who are interested.
-
Re:Takes the idea of "open source" to a new level
TPeople who don't use const correctness slow down their code
...That's actually a rather persistent misconception (usually). See Guru Of The Week 81
-
Re:Exception safety
Since I write C++ for a living, I have to ask, what's wrong with that line?
Consider the following code sequence:
QThingy *thingy = new QThingy();
justAboutAnything();Just about anything can throw an exception in C++. When that happens, thingy will never get deleted, causing a memory leak and, if thingy owns a resource, a resource leak. The fix is to use a managed pointer, such as std::auto_ptr, boost::shared_ptr or QSharedDataPointer. This also applies to class members.
You might like to read Exceptional C++ by Herb Sutter. It goes into these issues in some depth.
Of course if possible I'd put it on the stack, but sometimes it can't be avoided..
Of course, thanks to multi-threading, stacks are smaller than they used to be. If you want to put a large object in stack scope, boost::scoped_ptr might be appropriate.
I've never had a problem with exceptions in Qt-using code on any platform.
That's good to know, thanks.
-
Re:C++
cplusplus.com?
good lord no. use it for iostreams quick reference at most.
http://www2.roguewave.com/support/docs/sourcepro/edition9/html/stdlibref/index.html
http://www.dinkumware.com/manuals/Default.aspx?manual=compleat
note that dinkumware wrote much of msvc's c++ standard library.
-
Re:managed code
MS did do a lot of work (pretty poor IMHO though) with C++/CLI to get some interop going between C++ and C#/VB.
I think Herb Sutter did a pretty good job of explaining why they designed C++/CLI the way they did in this article on his website http://www.gotw.ca/publications/C++CLIRationale.pdf.
Except for some problems with boxing/unboxing(as in being a pain in the ass), I've not really ran into any problems using C++/CLI as a langauge on any of my projects. And unless your using the
/clr:safe flag, linking with "OLD" C++ should not be problem, every thing else being equal.And yes, while
.NET can be slow, inconsistent and otherwise a piece of s**t, for somethings it's all there is, atleast without rewriting/creating alot of code.BWP
-
Re:More than a trend, it's a necessityHerb Sutter's article The Free Lunch is Over is 3 years old now. His predicted Concurrency revolution hasn't happened. Using his lunch analogy, if you were given free lobster lunches for years and suddenly had to pay $100 for your lunch, you might find that you're really not very hungry or that you prefer cheese sandwiches.
The free lunch (in performance) used to get wasted on slack programmers ignoring performance. Faced with not slacking off further or mountain of bugs from multithreading or learning some new functional language made by academia, the average programmer will choose not slacking off.
-
The company logic
The companies' logic is that programmer cost a lot. It's actually much cheaper, they think, to throw some money in buying more hardware to make up for the lack of optimisations in the code, than to waster the precious ( = expensive in terms of salary ) programmer's time.
Where this is actually true remains to be seen.
Specially given the current trends in hardware (additional power doesn't come from more raw power but from additional parallelism, etc.) the programmers will have *anyway* to be clever, because better hardware won't be able anymore run the same shitty code faster.
As Herb Sutter puts it The Free Lunch is Over. -
Re:Fortran
Because there is no one true way to write a parallel program (it really depends on the algorithm), there will always be multiple frameworks to choose from. O well! The people who write parallel programs are typically smart enough to deal with excessive choices. (No comment on others).
You're right; there's nothing more tragic than watching a programmer butcher his well-written program in a futile attempt to make it fit the only concurrency model he knows. Closely associating a language with a single, well-designed concurrency framework would at best do the same thing for it that Rails did for Ruby: bring it a flurry of popularity in the short run and damage its reputation in the long run as people doggedly apply the framework to unsuitable problems and blame the language for the results.
On the other hand, at some point we're all supposed to face up to the end of the free lunch, and a fad for an exotic kind of concurrency might be a clumsy, spasmodic step in the right direction. -
Re:The problem with VC++Right, that's why they hired Herb Sutter as a software architect, right? You know, the Herb Sutter who is the chair of the ISO C++ standards committee.
Frankly, the extensions to handle GC are some of the best (and yes, innovative) additions to C++ I've seen in a while, and make C++/CLI the most versatile
.Net language IMO. I hope they make similar innovations in the area of threads (something Sutter has been talking about for years now). -
Re:Looks good, but a little hampered by C++Erm, yes, C++ has local classes, however there is a "BUT" and it's a big one:
Local classes / structs do not have external linkage and therefore can't be used as template arguments. So, for functors etc., which is precisely where you'd want something like a local class (ie. because you really want a closure), they are useless.
Do you know why that restriction is there? I hadn't been aware that this was possible before now, probably entirely because that restriction makes them mostly useless.
(And yes, that restriction seems bizzare enough that I went and found someplace that quotes the standard to verify it.)
-
Re:Size doesnt matter to me.
3ghz in less space than a dime! Cool, but why can't they just extend outwards?
Three words :
Speed Of Light
The clock speed (of a cpu) is limited by the speed of light, and the bigger the chip, the further stuff has to travel. Even at light speed, you can only go so far and get back again in a certain time.
I'm not brilliant at explaining this, but I'm sure someone else will pick this up.
In the meantime, have a look at this interesting paper from 2005. -
Re:More likely
Do you mean processing power, or clock speed? Clock speed was never a straightforward indication of processing power, although for a given architecture, generally a faster clock means more powerful.
I mean both. Clockspeed has been a good, general indicator of processing power. Yes, having a limited cache and sacraficing everything to clock speed like Intel did at one point can invalidate that, but despite all that clock speed has been the main driver when it came to "wait a couple of years" to solve your cpu-bound problem.
Just because designers have had to focus on other ways of improving a chip's performance, doesn't mean that progress has come to "an abrupt end".
But I think it has, and I'm not the only one. See The Free Lunch Is Over. For decades we've been spoiled by faster chips that made our software run faster without changing a thing. Now we have to focus on parallelizing our software, which is a huge paradigm shift and not easy to do. Also, don't forget Amdahl's Law, which places limits on how much adding new "cores" can help you.
My current PC (1.8GHz P4, 4 1/2 years old) has served me well given its age, but it's certainly not comparable to the machines on sale at present, regardless of its clock speed.
I'd say it compares pretty well, given its age. Consider that if clock speeds had kept up, they would be selling PCs with over 10GHz. I have a similar machine as yours, and I really have no desire to buy a new one. I don't have much use for 64-bits or more cores. I'd love to get my hands on a 10GHz one though
:)There's more general criticism on exponential technological progress on Wikipedia.
-
Re:Clearing things up a bit
Ignorance is bliss... http://www.gotw.ca/publications/concurrency-ddj.h
t m -
Concurrency in software
Herb Sutter wrote about this topic two years ago. A great read for anyone who is interested.
http://www.gotw.ca/publications/concurrency-ddj.ht m
Enjoy, -
Re:I have been convinced...
At some point in time, there will likely be a stall in speeding up hardware.
Yes, that's been the case for at least 4 years now. That's why there's been the push for multiple cores. The Free Lunch is Over
-
Re:No basic types
I'm not the poster of your post's parent, but I did a bit of searching (since I was interested too), and in most cases it seems to be simply that he believed that unsigned types just add complication to little real benefit. He often cites that Java was supposed to be reasonably simple to understand the semantics of, and that unsigned types tend to dilute that. I tend to agree (I never really "got" unsigned types), but here's some indicative quotes:
In programming language design, one of the standard problems is that the language grows so complex that nobody can understand it. One of the little experiments I tried was asking people about the rules for unsigned arithmetic in C. It turns out nobody understands how unsigned arithmetic in C works. There are a few obvious things that people understand, but many people don't understand it.
Q: Programmers often talk about the advantages and disadvantages of programming in a "simple language." What does that phrase mean to you, and is [C/C++/Java] a simple language in your view?
...
Gosling: For me as a language designer, which I don't really count myself as these days, what "simple" really ended up meaning was could I expect J. Random Developer to hold the spec in his head. That definition says that, for instance, Java isn't -- and in fact a lot of these languages end up with a lot of corner cases, things that nobody really understands. Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is. Things like that made C complex. The language part of Java is, I think, pretty simple. The libraries you have to look up.
Hope that's the sort of thing you were looking for.
:) -
Concurrent programming
it's just completely different from writing for a single core and requires programmers to think in ways that they never had to with single core programming.
I'll second that. You can read more about concurrent programming (and why it is vital to learn it) in Herb Sutter's excellent article, "The Free Lunch is Over".
(doh, reposted due to URL mangling) -
Exceptional C++
If you are a C++ programmer, I suggest reading Exceptional C++ and the other books in that series and the corresponding Guru of the Week archive. You can know a lot of C++ and not know much of what's in there. I found I had a much deeper understanding of C++ by reading it and my coding style has changed (for the better, I hope) as a result.
-
Exceptional C++
If you are a C++ programmer, I suggest reading Exceptional C++ and the other books in that series and the corresponding Guru of the Week archive. You can know a lot of C++ and not know much of what's in there. I found I had a much deeper understanding of C++ by reading it and my coding style has changed (for the better, I hope) as a result.
-
But remember, the Free Lunch is over!
Wonder how long it will take for compilers and languages to catch up with the concurrency challenges. Till then, applications will run slower than ever.
[On the desktop, multimedia players, browsers, compilers, IDEs, how many of them will use those cores? Servers seem to be ready though.] -
The Free Lunch is Over
I'm not sure that this has to do with a low-level/high-level language debate any more. Consider, for example,
that C++ offers both very low and very high-level semantics. When properly used, this yields high level
programs with excellent performance.
But, so what? Neither C++ today, or any other very widely-used programming language adequately manages the
real problem, which is concurrency.
Herb Sutter has written an excellent paper on this topic, called "The Free Lunch is Over". Let's get off this
hobby horse and on to some real (and interesting) problems!
Here is Mr. Sutter's article: http://www.gotw.ca/publications/concurrency-ddj.ht m -
Competition and Concurrent Programming
Intel designed the "ultimate" microprocessor - on paper. They might have been successfully in forcing every software company on the x86 instruction set to recompile but AMD saw the weakness in their strategy. Yes, x86 is weird, arcane, backwards, and messy. The instruction set is rooted in late 1960s and early 1970s computing. But, it would cost millions if not billions of dollars for the companies dependent on x86 designs to completely ditch the x86 architecture. AMD exploited this lack of foresight by Intel by offering a competing, well performing, backwards compatible chip to the Itanium.
All this is great news for the consumer except that there is an economic law of 3's. We need a third competitor in the space to truly get good competition. We used to have Cirrus but they died several years ago. A couple of other companies that had a license to the x86 instruction set also did not make the transition. The PowerPC and dead DEC Alpha are not options either. Ideally, if we had a third chip manufacturer I think, based on economic theory, we would see some really interesting and innovate things take place in the chip market - beyond what we currently have. And, it would be much more likely to be sustainable.
Using a backward compatible (and I mean x86 compatible) chip design is an easy decision for most technology companies. Option (a) spend millions migrating off the x86 to an even more proprietary Intel chip set or option (b) use AMD and operate on x86 as usual. Without a monopoly forcing option (a), option (b) was the clear winner. Intel has been forced to refocus their efforts and play "catch up" with AMD's new chip architecture and multi-core strategy. To make Intel's situation worse, AMD did some wonderful innovating on their. This helps no only AMD but all the programmers in the world that rely on the x86 architecture. Industry insiders are predicting the end of Moore's law. If you believe them then the free lunch is over. Chips are not going to operate at faster speeds. So, the only way to get more horsepower out of a machine would be to add more processors. But, most applications are written to run on single processor architecture. Most programmers know next to nothing about concurrent software design, testing, and development. AMDs chip pretends to be a single-processor machine while dividing tasks with multiple cores. Coding to true multi-processor systems is not only difficult but it is also not supported well in any language. For those that think C# and Java is the answer to concurrent programming, you might want to read what Herb Sutter has to say on the issue.
http://www.gotw.ca/publications/concurrency-ddj.ht m -
Re:Lack of threading is a benefit.
Also, as Moore's law is still going strong while CPU clock scaling is stalling we will, as you may have heard, see more cores on upcoming CPUs rather than faster cores. This means that we will be seeing a minor revolution in how software is built. It will become inpossible to write software with competitive performance without using threads.
The problems you (Russ) brought up are very real though, and there are several research projects in progress to try and adress them with "new" abstractions. One among many that is working on this is Herb Sutter, who gives his view on the matter here -
Re:Sounds like a molehill masquerading as a mounta
EDG is the only compiler to support the export keyword on templates, which allows the template definition to be separated from their declarations. It is a feature that is really complicated to implement and that does not seem to worth it.
I think that is what Mr Sutter meant when he said that EDG based compilers were the only 100% compliant compiler. More information is available on http://www.gotw.ca/publications/mill24.htm.
-
PS3 won't be taken advantage of fully for a while
Hopefully they will have had enough time to figure out how to code in a way that takes full advantage of the Cell. If all that we get is the equivilant of PS2 games with shinier graphics, then who really cares?
The Cell processor is highly centered around multithreading design and performance. To take full advantage of it will require extremely complicated programs that are multithreaded in such a way to take advantage of all 8 cores. No one in the industry has truely conquered this task yet. Even on the 360, which is also a multi-core system, 99% of the games you're seeing only use 1 of it's cores, however I think Ghost Recon coming up uses a 2nd but only for minor things.
There's a good article on this topic called "The Free Lunch Is Over".
The real "revolution" for both the 360 and the PS3 won't come for a couple years most likely. As it will take developers time to learn the best ways to develop for the hardware. This has always been the case with consoles, however expect the growth potential of both the 360 and PS3 to be massive compared to previous generations.
Anyway, if you're expecing the PS3 to do anything beyond what you've seen on the 360, at least for the first couple years of it's life, you're in for a huge let down. -
You're right, it's a major headache
Multicore CPUs, and multiprocessor systems, are only going to be as fast as the software can make them. Concurrency is a major focus of software programming research at the moment.
For some more info, check out:
The Free Lunch is Over, the article that sparked the discussion.
A talk Herb Sutter did on the Concur project, a research project into abstracting concurrency, sorry IE only but it's worth it -
Re:Where are the following?
Schildt's are ok but Herb Sutter's Exceptional C++ and More Exceptional C++ are more along the lines of "ok, I think know C++, but do I know it".
-
Re:Where are the following?
Schildt's are ok but Herb Sutter's Exceptional C++ and More Exceptional C++ are more along the lines of "ok, I think know C++, but do I know it".
-
Re:Parallel processing
The Short version: I agree with many of the points you make, but I think it's over simplified.
Let me take the main points as this could otherwise drag out...
"As I said, there are overheads associated with multiprocessing even in an ideal situation (which you almost never, if ever, have) so multi-core paralellism can never even be as good as a single core chip that goes twice as fast."
I can see where you're comming from, but I think you underestimate the cost that context swapping has. Let me define some terms:
I would say that most algorithms can benefit from parallel processing
I would say that most systems are built from many algorithms that can be handelled in parallel.
With correct design, mindset amd tools software can be written to take advantage of this massive parallelism.
We are much more limited by clock speed than by area in modern processors.
Memory access in modern processors is the main bottleneck for many algorithms.
Multi-threading in a single core makes better use of one memory because while one task is stalled on data from memory, the processors resources can be used for another thread that has its data sat in cache.
I refer to a thread as a very ambiguous concept, it could be a whole chip, it could be an execution context on an individual core.
If you had as many cores as you had x tasks and all tasks required the same ammount of processing (very unrealistic) then there would be no task swaps. If you then put this same problem onto a prosessor that was x times faster but only had 1 core then it would be slower because of the task swapping. How slower would depend on how often it had to swap.
Inter process communication which you say is a problem is indeed a problem, but not for all algorithms on all architectures. Take a network processor, often there are dozens of processors but the architecture is designed for this so there is lots of communicarion between the cores; so interprocess communication is not an issue.
As another example of inter-process communication take the transputer - that was even better as it had next to no cost for a context swap too.
Give me an example of a task an embedded device that is processor limited that couldn't be improved by more memory speed. I'll bet that this could therefore be helped by splitting the dataset up into multiple streams and running these on separate cores.
I really think all the problems you/we state are flaws in the current dominant architecture, not real limitations as I have worked with systems that have ways round them all.
Cranking up the clock speed has already hit a hard limit, like it or not if we want more speed, we have to think parallel. This is not a cheat, most systems are already parallel, so why not make use of this. Why go to an effort to serialise a problem just to put it on a single thread processor that could be a 10 thread processor.
But yes it would be nice to have a 5Ghz machine on my desktop, but it's not going to happen any time soon. simply to keep cranking up the speed is a very simple solution to the problem, but that's hit a limit. The free lunch is over, you may want this to happen, but magic is for what people want, engineering and science deals with what is.
I suggest a read of this:
http://www.gotw.ca/publications/concurrency-ddj.ht m
as it puts that argument far better than I could.
Multi-core may not be a fundamental advance, but you give me a single fundamental advance in computing since the 60s?
hey the 4040 wasn't a significant advance, as all it did was combine the separate parts into a single chip which had years of precidence anyway, so that's not a significant advance; the microprocessor was not a significant advance by those rules.
I think we can only judge what is a significant advance in retrospect and so far I'm seeing the mainstream thinking moving towards a more parallel one (which is what is happening) as being the f -
It's far too late"If you think C++ is not overly complicated, just what is a protected abstract virtual base pure virtual private destructor and when was the last time you needed one?" -Tom Cargill
The largest problem with C++ is its complexity. It is not just too complicated, it is *unmanageably complicated.* Some of the symptoms are:
- The STL has inexplicable omissions. For example, there's no portable way to seed the built-in PRNG in the random_shuffle algorithm, rendering it useless.
- Guruhood isn't good enough. Consider the seemingly simple task of creating a stack that works correctly with exceptions. It's extraordinarily difficult even for a guru.
- Language features interact in nonintuitive ways, producing a combinatorial explosion. For example, if you overload a function in a class, you don't have to use the scope resolution operator, and if you override a function, you don't have to use it either - but if you do both, you DO have to use the scope resolution operator or else you get a compile error!
-
No more free lunches; should we get used to it?
The article said that most developers would be using only one of the PS3's processors for most operations. Well, when you're used to designing for one processor, you tend to continue designing for one processor.
Not really surprising; at any rate, it may be essential to get used to this type of architecture/programming, as The Free Lunch Is Over, if this article is to be believed. (This may have featured in /.; I forget where I first saw it). -
A new demand for skilled developers
It's pretty obvious that the next wave of Moore's law seems to be moving computing towards parallelism.
This is pushing software developers to make their applications multi-threaded in order to exploit the performance gains of parallel processors.
The interesting thing about this is that writing concurrent multi-threaded applications is extremely diffucult. I expect there to be an increase in demand on skilled programmers in the near future to overcome this diffuculty.
Look at it this way: the increase in CPU speed has spawned the rise of programming languages with builtin memory management, thus making programming easier to do. By using higher level languages like Visual Basic, Python, and even Java, programmers generally no longer have to worry about memory leaks. This has made software easier to develop, and has made the programming profession possible for more people.
AFAIK, there exists no anlog for making multi-threaded applications easier to write. They're damn hard, and tracking down race-conditions where one thread's actions screw up another thread mid-step is a royal pain.
It seems to me that this is going to impose a pretty big limitation on the capabilities of entry-level developers. Until somebody develops some sort of fire-and-forget race condition prevention tool, it's going to pay to have skills as a multi-threaded app developer.
I guess all of those oldschool Solaris guys who have been bragging about having true threading with Java and C/C++ since 1995 are going to finally get their day.
For more reading, here's a good article about this stuff:
The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software -
Re: I don't "get" Mono either.
I noted that C++ code can be made portable by not using extern. The problem I pointed to was that separate compilation breaks down if you can't use extern.
The separate compilation often breaks even if you can use export. See section 14.6.2 of the standard or a detailed treatment by Herb Sutter for the reason why.
-
Re:Don't write C++ without boost!
Multiple auto_ptrs can point to the same object, but at most one should own it.
No, that's not right.
To see why, first consider what happens when you copy an auto_ptr: An auto_ptr owns the object that it holds a pointer to, and only one auto_ptr may own an object at a time. When you copy an auto_ptr, you automatically transfer ownership from the source auto_ptr to the target auto_ptr; if the target auto_ptr already owns an object, that object is first freed. After the copy, only the target auto_ptr owns the pointer and will delete it in due time, while the source is set back to a null state and can no longer be used to refer to the owned object. -
Re:Apple Methodolgy
Herb Sutter wrote an article that describes this much better than I can, but basically, you're not far off the mark...you shouldn't be seeing or expecting any major increases in performance via a faster clock, but by more cores and more multithreading.
It wouldn't surprise me a bit if Apple releases new machines to totally obscure the actual ghz number for some other selling point like number of cores or somesuch.