On 5/3/07, Erik de Castro Lopo <mle+la@mega-nerd.com> wrote:> Peter Grayson wrote: > > Personally I think universal binaries are a bad idea.They have obviously served some purpose, but I tend to agree that the concept does not seem to scale well once outside the Apple microcosm.> For one of my projects, libsndfile, endian issues is not the only > think that breaks in univesal binaries. The problem is that I > detect cpu features other than just endian-ness at configure time; > things that cannot be detected purely from compiler flags. > > See: > http://www.mega-nerd.com/libsndfile/FAQ.html#Q018Can you elaborate on what kind of CPU vagaries come into play besides endianess? Do they affect all code or just highly-optimized code? I have built several open source projects as universal binaries and they basically function. If you know of specific risks to look out for, your experiences would help a lot of people.> However, my biggest objection to universal binaries for libsndfile > is that libsndfile has a huge and comprehensive test suite and > running the test suite during a universal build will only test > the native build, not the cross-compiled build. As far as I am > concerned, cross-compiled code that isn't tested is worse than > native code that isn't tested and I consider native code that > isn't tested to be broken code.Is it just the endianess issue or is it other ill-detected CPU features that cause the libsndfile test suite to fail? Again, your experience would be greatly appreciated.> > My strong suspicion is that testing __BIG_ENDIAN__ at compile-time > > will work for all relevant unix-like platforms. Even icc supports > > this. > > Yep, gcc and icc support it. How many others do? Is suspect > its very close to zero.You are probably right. My argument here was bogus. Although, didn't some features get into the C and POSIX standards by first being non-standard, but useful? In this case, these macros are clearly an insufficient to be regarded as a solution to the problem, but they have proven useful to a number of people, including myself. Thanks for your feedback. Pete
Peter Grayson wrote:> Can you elaborate on what kind of CPU vagaries come into play besides > endianess?One issue I found was the cpu behaviour when converting from float/double to int32 when the source float is outside the range of values that can be represented by the int32. For instance: float int32_ppc in32_x86 2147483649.0 2147483647 -2147483648 2147483648.0 2147483647 -2147483648 2147483647.0 2147483647 2147483647 (0x7fffffff) .... -2147483648.0 -2147483648 -2147483648 -2147483649.0 -2147483648 -2147483648 (0x80000000) -2147483650.0 -2147483648 -2147483648 As you can see out of range floats are correctly clipped on PPC, but only correctly clipped for negative floats on x86. libsndfile has code a bit like this: if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= 1.0 * 0x7FFFFFFF) int_value = 0x7fffffff ; if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000)) int_value = 0x80000000 ; On PPC, the above two lines get optimised out. On Intel x86, only the second gets optimised out.> Do they affect all code or just highly-optimized code?The float -> int issue affects all code where the source float is greater than 0x7fffffff. Yes it is a rather obscure corner case.> have built several open source projects as universal binaries and they > basically function. If you know of specific risks to look out for, > your experiences would help a lot of people.AFAIAC, all code should have a test suite. For universal binary builds (and any cross compile builds), the test suite must be run on both platforms. Cheers, Erik -- ----------------------------------------------------------------- Erik de Castro Lopo ----------------------------------------------------------------- Saying Python is easier than C++ is like saying that turning a light switch on or off is easier than operating a nuclear reactor.
> One issue I found was the cpu behaviour when converting from > float/double to int32 when the source float is outside the range > of values that can be represented by the int32. > > For instance: > > float int32_ppc in32_x86 > 2147483649.0 2147483647 -2147483648 > 2147483648.0 2147483647 -2147483648 > 2147483647.0 2147483647 2147483647 (0x7fffffff) > .... > -2147483648.0 -2147483648 -2147483648 > -2147483649.0 -2147483648 -2147483648 (0x80000000) > -2147483650.0 -2147483648 -2147483648 > > As you can see out of range floats are correctly clipped on PPC, > but only correctly clipped for negative floats on x86.Well, AFAIK C89 says the behaviour in undefined, so I wouldn't rely on that too much. Even on PPC, it's quite possible someday the gcc folks will be able to 1) determine at compile time that a conversion somewhere will overflow and 2) optimise it out (since it's undefined anyway) or do other funny things with it. That's why I wouldn't depend on the right thing happening, even on PPC.> libsndfile has code a bit like this: > > if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= 1.0 * 0x7FFFFFFF) > int_value = 0x7fffffff ; > > if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000)) > int_value = 0x80000000 ; > > On PPC, the above two lines get optimised out. On Intel x86, only > the second gets optimised out.Sounds a bit dangerous to be considering what I wrote above. I tend to consider the following: "If your code depends on non-specified behaviour, sooner or later a gcc developer will come up with a clever way of breaking it".>> Do they affect all code or just highly-optimized code? > > The float -> int issue affects all code where the source float > is greater than 0x7fffffff. Yes it is a rather obscure corner > case.Well, how obscure it is really depends on the range of your samples. I'd tend to say that if you expect something that fits in 16-bits than you don't really care what happens if the input it 2^16 times too big, because it's catastrophic anyway.> AFAIAC, all code should have a test suite. For universal binary > builds (and any cross compile builds), the test suite must be run > on both platforms.I'm afraid I haven't been Doing It Your Way so far :-( But I'm quite willing to integrate contributed test cases :-) Jean-Marc