If every non-constant array index is bounds checked, and every pointer access is implemented via code that checks the pointer for validity first, then it will neither by 0.01% not 10 bytes more.
Compilers may reduce this by proving that certain accesses are always valid, but I believe the overhead will still be significant.
Sylvia.
Didn't find your answer? Ask the community — no account required.
S
Sylvia Else
I had to learn COBOL for my computer science degree (yes, I know that that dates me). What a waste of time that was.
Though I may have written the world's only data-driven COBOL program.
Sylvia.
J
John Miles, KE5FX
You can get 98% of the way there by forcing yourself to name variables with their units.
float delay_time = 123.456; // No, just no float delay_time_ms = 123.456; // OK
-- john, KE5FX
W
wmartin
That's also pretty handy for dimensional analysis...
C
Clifford Heath
You clipped the example that I was responding to, namely:
"quantities in newton/meters should be of type NewtonMeters and foot/pounds should be FootPounds, and casually performing operations with the two causes a compile error"
That's about dimensional analysis, not data representations. Strong types are a good thing too, but dimensional analysis might have stopped some stoopid Americans from crash-landing on Mars.
CH
C
Clifford Heath
Dimensional errors should also be compiler errors.
That's what he said, and that's what he meant.
Go read it again, see if your comprehension is any better this time.
CH
S
Sylvia Else
Well, other than Algol we didn't have to learn those.
I do remember writing something in a weird dialect of Algol released by Xerox, where all the reserved words had to be quotes. But that must have been while I was working for a year before I went to University.
No idea. I was at uni in the late 70s
Could probably have been done just as well in Fortran.
Sylvia.
B
bitrex
That's cool and you should do that anyway, but user-defined types can also contain their own logic and enforce their own usage, like a type called Age or ElapsedTime or suchlike won't let you do something like Age age = -5 (or some non-contrived operation where the result is materially equivalent.)
S
Sylvia Else
Using a punch? Sheer luxury. We were using coding sheets that managed to be garbled by punch operators.
Fortunately, this was before the time when most people could type, and the few machines available to students were not much used, other than by me.
Also, the place I was working during the holidays was a time-sharing service (remember those?), so I did most of the COBOL work there.
Sylvia.
S
Sylvia Else
The time-sharing service I worked at provided dial-up access, at 110 baud. Even in-house, we were mostly limited to 110 baud teletypes, which were in a separate room because they were so noisy.
Hard to imagine now.
Sylvia.
J
John Robertson
Poketa, poketa, poketa...
Nothing like the sound of an EM machine running happily!
John ;-#)#
U
upsidedown
In industrial control systems in addition to the actual measured value (e.g. from an ADC) you also have a separate data quality variable and often also a time stamp (sometimes with a time quality field, resolution, synched etc.).
In the 8/16/32 bit data quality variable, you can report e.g. overflow, underflow, frozen (old) values, faulty value (e.g. ADC reference missing or input cable grounded, manually forced values etc. The actual value, data quality and time stamp are handled as a unit through the application.
If some internal calculation causes overflow, the overflow bit can be set in the data quality variable or some special value replaced and a derived value data quality bit can be set.
When the result is to be used for control, the data quality bits can be analyzed and determined, if the value can be used for control or if some other action must be taken. Having a data quality word with every variable makes it possible have special handling of some faulty signals without shutting down the whole system after first error in some input or calculations. Such systems can run for years without restarts.
In IEEE floats, there are some rudimentary possibilities to inform about overflows (+/-infinity) Not a Number (NaN), but using a separate data quality variable with every signals allow a much wider selection of special cases to be monitored.
M
Martin Brown
Back in the day BCPL was an example of a compiled language that was fairly trivial to bootstrap quickly onto a novel processor.
FORTH was another that was quite good on embedded stuff but it tended to be very much a write only language and maintenance was a nightmare. It was an instant hit in some observatories for telescope control.
Modern languages seem to have pretty good back end cross compilers.
I have all the very processor specific bits in a module with the name of the processor included. Flags in the main program include file adjust what is hidden from compilers that won't understand it.
Intel no longer defining __INTEL_COMPILER in its latest offering caught me out. It is now __INTEL_LLVM_COMPILER :( How daft can you get!
BTW does anyone know of a #define in the MS C++ compiler that is set when the advanced vector linkage mode is enabled? I haven't found one!
U
upsidedown
Depending on how the Y2k fix was done.
If 2 digit fields are retained, it might work for 1950 to 2049 (or
1980 to 2079). With 4 digit year, some system will fail after Feb 28
2100, since this year is not a leap year.
Year 2038 is an issue on Unix/Linux/C/C++ based systems using second count since Jan 1 1970.
P
Phil Hobbs
But program memory is still at a significant premium--more expensive and harder to get. (We went through a lot of pain due to the LPC845 becoming unobtainium for 18 months--porting to the 825, going to two processors instead of just one....)
Once again, this pleasant strategy assumes that you have enough flash to hold the full debug version of the code, which is far from universally true.
Well-aged shelfware is always the best. ;)
Cheers
Phil Hobbs
D
Dimiter_Popoff
On 2/24/2023 15:13, Phil Hobbs wrote:
......
Of course so but... sometimes even 20 years can be less than "well aged", as I found out not so long ago. A customer to a new product line (the tld readers,
formatting link
) brought two units for maintenance (they had managed to injure the HV cable so it would occasionally trigger the overcurrent protection etc.) and I set to install the latest version of dps, nuvi and all as I had the units here and would not need to call and ask for repower if I messed something up doing all that online.
So I left them run in a loop to see they would do 2000 measurements with no issues and found out they would crash somewhere between
500 and 1500 depending on luck (took hours to get there, some 10 seconds per measurement). I could see which task was *usually* doing an access to unallocated memory but things were messed up enough so the unit needed a reboot. It took me perhaps *a week* to find out what was happening. It turned out the visualization task for a tld spectrum - very similar to that for a pha spectrum for gamma, alpha etc. but new and obviously MCS, not PHA - was using floating point a lot and someone had forgotten to turn on the "save the fp regs" for that task properly. Wait, "someone" could only be the person written all that... Then while converting an FP to decimal so it can be shown the system call would divide by 10 in a loop and stack the ascii numeric characters (so they can be unstacked in the wanted order), relying on not being able to get more than 32 positions. Even if more they would go below the stack pointer which usually has (and had in this case) a lot of spare room and it would be just a wrong number being shown. However if the task doing that conversion would happen to be preempted while doing it - and not have its FP regs saved - and get the divisor, the 10, switched to say 1.... the number of positions would get indefinite and all the stack was full of ascii zeroes, $30. Which is why the bad address another task, usually the HV control task - having a common with the the visualization one - went for address $3030303x something, this after plenty of other crucial stuff being smashed. Now, perhaps 20 years later, I added a limiting counter to that stacking loop.... Might save me some day if I forget to save the FP regs one day again :).
Anyone who is serious about timing code knows how to read the free running system clock. RDTSC in Intel CPUs is very handy (even if they warn against using it for this purpose it works very well).
Other CPUs have equivalent performance monitoring registers although they may be hidden in some fine print in dark recesses of the manual.
These days most binary operations are single cycle and potentially less if there are sub expressions that have no interdependencies. Divides are still a lot slower. This makes Pade 5,4 a good choice for rational approximations on current Intel CPU's the numerator and denominator evaluate in parallel (the physical hardware is that good) and some of the time for the divide is lost along the way.
In the old days we were warned to avoid conditional branches but today you can get away with them and sometimes active loop unrolling will work against you. If it has to be as fast as possible then you need to understand every last quirk of the target CPU.
Speculative execution is a bit like quantum mechanics in that it explores both paths simultaneously and then the wavefunction collapses onto the path that was taken once the outcome of the comparison is known. This significantly alters the viability of some algorithms.
The only caveat is that everything stops dead if two divides or comparisons occur before the previous has completely finished executing and you get a hard pipeline stall (a very bad for speed).
How fast things will go in practice can only be determined today by putting all of the pieces together and seeing how fast it will run. On some CPU's Halley's more complicated 3rd order method runs as fast or sometimes faster than the more commonly used Newton-Raphson.
This has changed quite recently. On an i5-12600 they benchmark at 25 cycles and 26 cycles respectively but Halley has cubic convergence whereas NR is only quadratic (and intrinsically less stable).
Benchmarks can be misleading too. It doesn't tell you how the component will behave in the environment where you will actually use it.
I have a little puzzle on that one too. I have some verified correct code for cube root running on x87 and SSE/AVX hardware and when benchmarked aggressively for blocks of 10^7 cycles gets progressively faster it can be by as much as a factor of two. I know that others have seen this effect sometimes too but it only happens sometimes - usually on dense frequently executed x87 code. These are cube root benchmarks:
I also have to mention how impressed I am with the latest 2023 Intel compiler - their system cbrt is more accurate than is possible with a strict 64 bit only FP representation and fastest too!
Sneaky use of fused multiply add allows very precise refinement of the answer using more than the 53 bit mantissa of 64bit FP.
System cbrt on GNU and MS are best avoided entirely - both are amongst the slowest and least accurate of all those I have ever tested. The best public algorithm for general use is by Sun for their Unix library. It is a variant of Kahan's magic constant hack. BSD is slower but OK.
This is amazingly a best buy thanks to remarkable recent speed improvements in exp and log library functions (and also sqrt).
double cbrt(double x) { double y, t; if (x == 0) return x; if (x > 0 ) y = exp(log(x)/3); else y = -exp(log(-x)/3); t = y*y*y; return y - y*(x-t)/(x+2*t); // Halley refinement }
Is faster than most other algorithms at least on Intel CPUs and as accurate as all but the very cunning Intel C++ library routine.
PS don't be tempted to algebraically rearrange to y*(2x+t)/(x+2t) It might look neater but you will lose (at least) a factor of two numerical precision by using that form of the expression.
To make a horrible mess. Few problems scale well on multiple CPUs.
You may not think you need one but you do need a way to share the physical resources between the tasks that want to use them.
Cooperative multitasking can be done with interrupts for the realtime IO but life is a lot easier with a bit of help from an RTOS.
J
John Larkin
I like to raise and lower a port pin and scope it. One sees interesting patterns.
In most electronic instruments, an IRQ can do the realtime loop, and the main program can just be a simple state-machine loop with flags to/from some interrupt handlers. That's even better on a dual-core ARM.
I've written four RTOS's so far but have mostly decided that I don't need them. Most electronic instruments don't interact with local screens or keyboards or printers so don't need any persistant contexts.
L
Liz Tuddenham
I learned Algol in the 1970s to sort out the results from a data logger (program on cards, data on punched tape). Most of my life was spent working in analogue until, about 5 years ago when I needed to do some programming in PHP. To my surprise I hardly had to make any changes to Algol for the machine to accept it as PHP.
J
John Robertson
If you need schematics or advice I may be able to help...and there is still some life on rec.games.pinball!
John :-#)#
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.