Programs tend to do a lot of array access, and pointer references. Even if you may think you're just crunching data, that has to come from somewhere, and the results have to be stored somewhere. So the time and memory consequences of array bound and pointer validation are not trivial.
Sylvia.
Didn't find your answer? Ask the community — no account required.
A
Anthony William Sloman
It's called a grid-scale battery. Pumped storage is another solution. Hydroelectric dams don't tend to freeze up and the compressed air equivalent is even less likely to get messed up.
Emergency situations call for stored energy, and tanks of fossil fuel aren't the only option these days, though half-wits like Jan Panteltje can't imagine anything they haven't actually used.
M
Martin Brown
Agreed you don't want to do it on a heavily loaded machine but if you take an average over 10^6 function calls the OS noise is greatly diminished. Roughly a second is good enough for 3-4 sig figs.
Design of algorithms is always important and knowing when to break the rules is too. Fancy sorts on very short lists don't work too well.
Cache line behaviour is very difficult to understand. I have some code which flips between two different benchmark speeds depending on exactly where it loads in relation to the 64 byte cache line boundary.
That is always a problem as is memory fragmentation in kit that runs for extended periods of time and allocate buffers of widely varying sizes. Many domestic routers have this problem after a month or so of up time.
GC is the enemy of hard realtime work. By Murphy's Law it will always get invoked just when you need every last uS you can glean.
I remember those days somewhat unfondly.
You generally end up bound to one family of CPUs. We didn't always pick wisely and I variously backed Zilog Z8000 (remember them?) and the brilliant for its time NEC 7210 graphics processor. OTOH we did OK with TI 99xx/99k Motorola 68xx/68k and Intel x86 so I can't really complain.
My time doing that sort of embedded realtime stuff the battle was mostly to get the entire thing to fit in a 4k or 8k ROM somehow! To some extent it would be whatever speed it could manage and any glaring deficiencies in performance would be dealt with once it was all functional.
It is getting harder to predict this.
Even when you are controlling the benchmarks you can still get anomolous results. The fastest cbrt in a bechmarking loop is not always the same as the fastest on in a real world solve a cubic equation program!
So did compilers. I knew one lot who recognised certain of the common benchmarks and specifically optimised to be top of the table in some.
It is quite reproducible and others see it too. The results are consistent and depend only on the number of consecutive x87 instructions. The results for non-x87 code are rock solid +/- 1 cycle.
In this case correctness is taken as a given - there are other performance tests against known difficult edge cases and random input with a distribution that focusses down on the most difficult region.
I recall someone left an undocumented booby trap of that sort in a 68k Unix port knowing full well that when they left the company (which they intended to do fairly shortly) someone would fall into it.
I have done simple things on PICs with everything in a loop and the odd ISR like a bare metal LCD display - 16877 has just enough pins for that.
What used to annoy me (and still does) are programmers that think their task should always have the highest priority over everything else.
In any serious multiprocessor you quickly learn that the task that keeps everything else loaded with work to do is critical to performance.
M
Martin Brown
You can have different interpretations of the language that either implement strict stack overflow, array bounds and numeric overflow failures like divide by zero, sqrt(-1) a hard fault.
I recall one teaching compiler that by default would generate a hard trap code for using an uninitialised variable. It was easy enough to have it as a compile time warning but you had to RTFM to find out how to do that. Few of the students ever did - only the brighter ones...
BOUND dates back to iAPX 186 ~1995? although I have never seen it used that way in anger. OS/2's page descriptor tables gave very robust control of what you could do to a chunk of memory. Any bad access was terminal for the offender and unable to affect any other processes.
The old smash along strings copying everything until you finally hit a null terminator is now deprecated. Most compilers warn against it...
Quite a few have debugging modes where protective filler is used to make uninitialised variables visible to the runtime system and so that overwriting the end of allocated memory by modest amounts harmlessly corrupts some padding added there for catching fence post errors.
There is no reason why C/C++ could not range check static arrays or even dynamic ones. It knows at runtime how big they actually are.
The big difficulty in C is with raw pointers to a God alone knows what. MS delighted in such horrid constructs as a part of the Windows code.
Flat memory architecture is the enemy of robust behaviour here. If you can construct a pointer to someone else's task and have write access then there is scope for doing a lot of unintentional damage.
Preventing user data from being executed makes things a lot safer too.
The best of both worlds is a debugging environment that protects the innocent from the most common mistakes we humans make either by compile time static code analysis (which has come on a long way from Lint) or by adding sufficient runtime checks to trap a decent fraction of them.
Fence post errors with binary logic are particularly bad news.
Like the raise undercarriage command that wasn't prevented from being used when the plane was on the ground or the plane that flipped itself over when crossing the equator. It is traditional for UK gunnery tables Coriolis force correction to be wrong in the Southern hemisphere too - a failure that continued as late as the Falklands war (at least at the outset). They realised PDQ that the "correction" was doubling the error!
Comp.risks is littered with coding mistakes that really should never have happened but the pointy haired boss said "ship it and be damned".
J
John Larkin
The future is lots of CPUs. Task switching and CPU contention are so last millenium. Each process can just own a CPU or three.
D
Dimiter_Popoff
Getting rid of task switching won't make your life much easier, in fact I don't see how it has made anyone's life harder. You still have to manage resources, like memory, file system, manage locks etc. etc. Task switching will remain as far as I am concerned, however tasks get also a "current core" in their descriptor. Of course it can be wise to have some core(s) assigned to some particular task when practical. Multiple cores do not make "do it and go to sleep" any simpler either.
P
Phil Hobbs
That works a lot better with multiple MCUs than with a fast multicore chip.
Cheers
Phil Hobbs
J
John Larkin
Why?
A multicore chip can share memory regions and such for zero inter-processor overhead.
Somebody recently introduced a 128-core ARM chip. That's a good start. It was historical to treasure a CPU as a rare resource, but no longer.
J
Joe Gwinn
It's a whole lot better than copying the bulk data back and forth, and is pretty much essential for embedded realtime, where most often there is neither time nor space for making copies.
In computer science, this is called a blackboard system (later, elevated to a design pattern), and they think that they invented it, but was universal for decades before.
In assembly, it was the natural design. In Fortran, it was called COMMON, and later GLOBAL COMMON (when it spanned more than one process space). IN POSIX/Linux, it's called shared memory. And so on.
.
formatting link
True, Moore's Law has turned CPUs into jellybeans. Actually, jellybean dust, a million per jellybean.
But the more fundamental limitation is Amdahl's Law, which applies to all parallel computations:
.
formatting link
This is why it's hard to parallelize for instance a FFT.
Joe Gwinn
J
John Larkin
That's a different problem. The big virtue of a many-CPU system isn't raw compute power - which we seldom need - it's simplicity and security.
There would be speed advantages not from sheer horsepower, but from keeping some OS blunder from locking up the whole system for minutes at a time. Again, stop thinking of CPUs and compute power as rare resources.
Of course, a many-CPU system would need a modern OS. It would run on one of the cores and manage absolute hardware protections of all the rest.
D
Dimiter_Popoff
They are less rare of course but they do consume power and even when put to sleep the leakage is huge on technologies which allow so many cores (say sub 20nm) so you have to unpower them then turn on etc. But all this is doable and is being done already, at some latency cost which is acceptable.
This is a somewhat naive view :-). Each core has its own MMU to begin with, as of today.
OS complexity is not your enemy. Shared memory bandwidth is, sync facilities etc. have to be deal with. I have had fun with a two core machine (one 68340 and one 8240) sharing each other's address spaces, one of them doing disk and ethernet access serving it to the both, that some 20 years ago. It has more challenges than one might anticipate :-).
But overall you are correct, cores will become more and more. Perhaps simpler types, perhaps a lot simpler than we know them now.
C
Clifford Heath
I recall seeing a dual 6802 processor around 1982 which had the CPUs working on opposite clock phases sharing the same address and data bus. I seem to recall the memory cycles only used half a processor cycle, but perhaps there was memory cycle stretching for collisions (or was that a different project?). Anyhow, cool at the time.
W
whit3rd
I recall a CDP1802 design that did the same thing; the chip was primitive, but it did tolerate clock stoppage to release the memory bus.
D
Dimiter_Popoff
There should have been no need for stretching, for the 6800 (02 was the same, just with a clock generator included) it takes just shifting the clocks at 180 degree and provide the memory is fast enough to do it in half a cycle. I have done this for a 6809 and a 6845 (a CRT controller) more than once. Later (early 90-s) sharing the memory with no clock stretching for a CPU32 (a 68340) was somewhat trickier but I still managed it, took fast enough memory and some more complex logic (in a 16v8... :) to shift the accesses by a cycle (may be also by 2, don't remember) depending on how the CRT controller (a Hitachi spinoff of the 6845 for LCD displays) clock would meet the CPU access.
P
Phil Hobbs
What for? Bitcoin mining? ;)
High performance takes a lot more than just multiplying the number of cores--the architecture is key. If you want an N-core CPU to be a symmetric multiprocessor (SMP), i.e. to look like a very very fast uniprocessor running N hardware threads, you need good cache coherence, which becomes very difficult for large N.
Cache coherence traffic scales as N**2 to N**3, depending on your assumptions (I mostly forget the exact criteria.) That gets difficult very fast as N grows. Thus highly-multicore processors are nonuniform memory access (NUMA) designs, leading to all sorts of complications in the programming model, and great difficulties in performance modeling.
Then there are the well-known issues with multiprocessing, e.g. the thundering herd problem, the deadly embrace problem, and so forth.
I've fought those wars myself. Some years back I did a clusterized 3-D electromagnetic simulator for my antenna-coupled tunnel junction project, and spent some years helping a bunch of other folks with scaling and interconnection issues.
Resource contention, interrupt priority, design compartmentalization, design reuse, yada yada, generally favour separate MCUs for different jobs. In an instrument, heavy computation of the sort that needs several cores sharing memory is best done in an FPGA, I think.
FPGAs aren't well suited to general purpose computing due to the gigantic overhead of task-switching, but in an instrument that's not an issue.
In product design, the one ox/two horses/1024 chickens tradeoff definitely goes "cluck cluck".
Cheers
Phil Hobbs
U
upsidedown
If you have a lot of cores, why not use discrete FT instead of FFT, especially if you do not need all points or the input size is something different from some power of 2 ?
P
Phil Hobbs
There are fast algorithms for all array lengths, including prime numbers. See e.g.
formatting link
. FFTs can be parallellized reasonably well. IIRC it's the bit-reversal step that makes radix-2 transforms a bit slow on highly multicore SMPs.
formatting link
Cheers
Phil Hobbs
J
Joe Gwinn
Actually, the problem is with all integral transforms, regardless of the existence of a fast algorithm, because by definition an integral transform uses the entire input to generate each point in the output.
But there are problems where there are things that can be computed in parallel independently. These are called "embarrassingly parallel" problems.
Joe Gwinn
J
Joe Gwinn
Yes, all true. But in radar we often want million-point (2^20) discrete Fourier transforms.
The bottom line for attempts to do just that were that time (latency) to done ceased decreasing and began increasing somewhere around 4 to 6 parallel processors.
This was a big problem because (marketing?) people assumed that if you used 10^4 processors, time to done would be reduced by 10^4. Oops. Even after people decided that 256K (2^18) points would suffice, still no go. They also believed the marketing MIPS of the computer platform, but that's another story. All these fables were killed by a direct FFT benchmark.
The eventual solution was to use specialized array-processing hardware.
Joe Gwinn
W
wmartin
Usenet needs a "dead horse language", to speed up describing all the dead horse beatings...
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.