The problem was one of computer science, but Kiki, filled with
resentment if not hate, kept whining that it was off topic because C
Sharp could handle the problem with ease.
Yes, C# can indeed handle the problem. However, it's not exactly all
that
"efficient" because it needs to do a full blown copy-on-write and use
garbage collection to ensure that everything works as expected. In other
words, I cannot operate on data-structures directly like I can using
assembly language. FWIW, this is exactly how Sun implemented
`AtomicStampedReference'.[...]
Can't you just let Moore's Law handle "efficiency"?
That's a fair point Edward, however I am highly interested in exploring
techniques that allow software to have excellent scalability, throughput and
performance characteristics on multi-processor systems. If the algorithm
does not scale well, then it's basically dead in the water wrt upcoming
many-core systems.
IMHO, it's not really enough anymore to simply think in terms of `faster
clock rate's = faster software'. Instead, you need to think about how your
software can possibly scale up and adapt to a new system that might have 5
to 10 times the number of processors that you are normally accustomed to
working with. For instance, imagine a software product that runs great on a
4-core system. Then one it's users purchases a 64-core system and installs
said software and does not see any speedup whatsoever. Well, the call to
customer service might go something like:
"I just purchased one of those new multi-core systems, and your application
suite seems to execute critical tasks a little bit slower than usual! Why is
that? Do I have to set some special configuration options? Please help..."
That's right, a poorly written multi-threaded application could actually
perform worse in a multi-core environment. I believe a company would have an
advertising and promotion advantage if it were able to say:
"Our company has recently accomplished the steps that are necessary in order
to create high-end software that is able to efficiently address the
concurrency revolution that is currently underway in the programming
community."
IMHO, software developers should try and learn how to properly address the
"Rise of the Multi-Core Machines!" in order to create quality highly
scaleable products that the consumers deserve. FWIW, here is an article by
Herb Sutter that just might be of interest to you:
http://www.gotw.ca/publications/concurrency-ddj.htm
Sure, not everything can be interpreted since this would multiply all
times by a constant or even a variable number of times because when
things are interpreted, something happens for each instruction. But as
I have shown, C sharp is compiled at the last minute and not
interpreted.
In my view, garbage collection is such a great thing that we shouldn't
be sad that it happens.
I think that garbage collection is an extraordinary convenient tool indeed
and, IMVHO, it's definitely worthwhile to try and reduce the
"burden/pressure" on it in order to help make it's job "easier". So, I think
that some forms of manual memory management can indeed be beneficial in a
fully garbage collected environment. For instance, something as simple as an
object cache can potentially help out things out:
Imagine a simple container in which you push/pop references to objects. Now,
on every push operation you allocate an internal node to hold the reference
and insert it into the collection. On every pop you remove a node a return
the reference. No need to explicitly free any internal nodes because the GC
just handles all if it for you; very nice! However, this can begin to build
up nodes that "do not necessarily have to exist". Think of pushing and
popping 10,000 nodes. Now, those 10,000 nodes might still exist even though
the collection is completely empty. Then you push and pop 10,000 more. Now
there might be 20,000 nodes floating around waiting for the GC to kick in
and clean everything. This is due to the non-deterministic nature of a
general purpose GC.
Okay, so what would happen if you used a simple node cache? The push
operation would check the cache and only allocate new nodes if it was empty.
The pop operation just sticks popped nodes into said cache if the number of
nodes it currently contains is below a certain threshold, say 50,000 nodes.
In this scenario, when you push/pop 10,000 nodes and then push/pop 10,000
more you are guaranteed to only have 10,000 nodes in existence. Therefore, I
kind of think that the GC would be fairly happy that you actually took the
time to take some of the pressure off of it. Yes, this is definitely a form
of manual memory management which is more complicated and error prone, but
it does have it's perks... ;^)
Is that making any sense Edward?
However, I have NEVER programmed OSen or embedded systems for real
money, although I've written a number of compilers. I understand that
absolute performance goals may apply. I do object to treating
performance speed as an unalloyed good when the customer doesn't ask
for it.
I think that one class of software than can benefit from heavy optimizations
could be database servers. If a company upgrades their server farms with
higher end systems that have many more cores inside of them and your
database software does not scale up, well, then they are probably going to
be extremely pissed of. I would not want to receive that phone call; yikes!
:^o