Tell PG: When I submitted this article, HN stripped the "!" characters out of the title...but I was then able to edit the story and put them back in there. I suppose that means there's a small bug in there somewhere...
Ahah, Apple does have different math
11–20 of 37 posts
Re: Ahah, Apple does have different math
#12It has been long known that one cannot rely on floating point for precise calculations, e.g. monetary values. One should use integers instead or some kind of other precise representation. But it does surprise me that even on the same CPU architecture you cannot expect every machine to produce the same results.
For example, on x86, many C / C++ compilers interpret long double as a 64-bit float while others interpret it as 80-bit extended precision.
And extended precision TBYTE (in Intel syntax) does actually take up 10 bytes. There's a speed loss for not aligning, but no correctness loss. In a possibly related note, however, Apple has bizarre and unnecessarily strict alignment policies for Mac OS on x86:
Re: Ahah, Apple does have different math
#13Re: Ahah, Apple does have different math
#14It has been long known that one cannot rely on floating point for precise calculations, e.g. monetary values. One should use integers instead or some kind of other precise representation. But it does surprise me that even on the same CPU architecture you cannot expect every machine to produce the same results.
For the same CPU architecture, compiler and FPU control word , you should expect the same results. For example, on x86, many C / C++ compilers interpret long double as a 64-bit float while others interpret it as 80-bit extended precision. And extended precision TBYTE (in Intel syntax) does actually take up 10 bytes. There's a speed loss for not aligning, but no correctness loss. In a possibly related note, however, A…
That's a stretch. Just because it's called "GCC" doesn't mean it behaves exactly the same on every platform, even if the CPU architecture is the same.
Apple makes extensive modifications, has their own ABI (see below), etc.
In a possibly related note, however, Apple has bizarre and unnecessarily strict alignment policies for Mac OS on x86:
It's not "bizarre and unnecessarily strict" if you want to be able to rely on SSE2+. Apple had the advantage of being able to define their ABI without regard to most legacy concerns, and so they did.
The reason that it's strictly enforced everywhere is that since Apple's compilers use SSE2+ they must be able to assume that, at function entry, the stack is properly (16 byte) aligned.
I understand your pain -- I've had to update a JIT implementation to deal with this, along with quite a bit of assembly that assumed 4 byte alignment, but Apple's reasoning makes sense.
See also: http://stackoverflow.com/questions/612443/why-does-the-mac-a...
Re: Ahah, Apple does have different math
#15Re: Ahah, Apple does have different math
#16It has been long known that one cannot rely on floating point for precise calculations, e.g. monetary values. One should use integers instead or some kind of other precise representation. But it does surprise me that even on the same CPU architecture you cannot expect every machine to produce the same results.
For the same CPU architecture, compiler and FPU control word , you should expect the same results. For example, on x86, many C / C++ compilers interpret long double as a 64-bit float while others interpret it as 80-bit extended precision. And extended precision TBYTE (in Intel syntax) does actually take up 10 bytes. There's a speed loss for not aligning, but no correctness loss. In a possibly related note, however, A…
Wait a minute, does that mean that floating point types don't have a stable ABI? If I have a library with function foo(float bar) compiled with compiler A, then it's not safe to compile an app - that uses that library - with compiler B?
Re: Ahah, Apple does have different math
#17Earlier quoted context omitted.
For the same CPU architecture, compiler and FPU control word , you should expect the same results. For example, on x86, many C / C++ compilers interpret long double as a 64-bit float while others interpret it as 80-bit extended precision. And extended precision TBYTE (in Intel syntax) does actually take up 10 bytes. There's a speed loss for not aligning, but no correctness loss. In a possibly related note, however, A…
For the same CPU architecture, compiler and FPU control word, you should expect the same results. That's a stretch. Just because it's called "GCC" doesn't mean it behaves exactly the same on every platform, even if the CPU architecture is the same. Apple makes extensive modifications, has their own ABI (see below), etc. In a possibly related note, however, Apple has bizarre and unnecessarily strict alignment policies…
Re: Ahah, Apple does have different math
#18Earlier quoted context omitted.
For the same CPU architecture, compiler and FPU control word, you should expect the same results. That's a stretch. Just because it's called "GCC" doesn't mean it behaves exactly the same on every platform, even if the CPU architecture is the same. Apple makes extensive modifications, has their own ABI (see below), etc. In a possibly related note, however, Apple has bizarre and unnecessarily strict alignment policies…
The stack is not actually aligned on function entry, because the return address is on top, so more alignment will be needed to avoid SSE2 locals being misaligned. It's not so hard for the callee side of the ABI to make sure the stack is aligned if it's going to use SSE2 and friends; it's rather more onerous to require every call site to make the alignments for the benefit of the callee.
The stack has --known alignment-- on entry, which removes the need to compute alignment at runtime. Any other approach requires more instructions overall.
It's not so hard for the callee side of the ABI to make sure the stack is aligned if it's going to use SSE2 and friends; it's rather more onerous to require every call site to make the alignments for the benefit of the callee.
I disagree that it's onerous. It seems silly to increase the runtime costs in exchange for a minutely simplified compiler port. It's not as if non-4-byte aligned ABIs are unusual.
Re: Ahah, Apple does have different math
#19Earlier quoted context omitted.
For the same CPU architecture, compiler and FPU control word , you should expect the same results. For example, on x86, many C / C++ compilers interpret long double as a 64-bit float while others interpret it as 80-bit extended precision. And extended precision TBYTE (in Intel syntax) does actually take up 10 bytes. There's a speed loss for not aligning, but no correctness loss. In a possibly related note, however, A…
> For the same CPU architecture, compiler and FPU control word, you should expect the same results. Wait a minute, does that mean that floating point types don't have a stable ABI? If I have a library with function foo(float bar) compiled with compiler A, then it's not safe to compile an app - that uses that library - with compiler B?
For example, the following C statement:
printf("%d\n", sizeof(long double));
gives the following results on my box: Cygwin gcc: 12
MSVC: 8
Embarcadero bcc32: 10
So yes, if you are assuming that foo(long double bar) - that specific header definition - compiled with compiler A will be binary compatible when compiled with compiler B, then you are not necessarily safe.Just `float`, though, is rather more solid.
Re: Ahah, Apple does have different math
#20Earlier quoted context omitted.
The stack is not actually aligned on function entry, because the return address is on top, so more alignment will be needed to avoid SSE2 locals being misaligned. It's not so hard for the callee side of the ABI to make sure the stack is aligned if it's going to use SSE2 and friends; it's rather more onerous to require every call site to make the alignments for the benefit of the callee.
The stack is not actually aligned on function entry, because the return address is on top, so more alignment will be needed to avoid SSE2 locals being misaligned. The stack has --known alignment-- on entry, which removes the need to compute alignment at runtime. Any other approach requires more instructions overall. It's not so hard for the callee side of the ABI to make sure the stack is aligned if it's going to use…
And it's not a "minutely simplified compiler port". That statement is startlingly naive. Do you have any idea how much hand-coded inline assembly, both in the runtime library and in customer code, needs to be carefully reviewed and modified to port from a platform without this requirement to one with it? Particularly since almost every other platform targeting the same architecture doesn't have the requirement?