Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > 32/64 bit cc differences

Reply
Thread Tools

32/64 bit cc differences

 
 
Eric Sosman
Guest
Posts: n/a
 
      01-10-2014
On 1/10/2014 5:05 AM, JohnF wrote:
> I'm getting a tiny-cum-microscopic, but nevertheless fatal,
> difference in the behavior of the exact same C code compiled
> on one 64-bit linux machine...


I concur with Ben Bacarisse's assessment of the code's
readability; my head hurts, too! But I toughed it out with
Tylenol long enough to notice one possible source of trouble:
Your pseudo-random number generator produces `float' values.
Even if the internal mechanics of the generator are accurately
reproduced on all systems, the actual values used in subsequent
computations might not be. The C Standard gives implementations
some freedom in floating-point calculation, in particular:

"Except for assignment and cast (which remove all extra
range and precision), the values yielded by operators with
floating operands and values subject to the usual arithmetic
conversions and of floating constants are evaluated to a
format whose range and precision may be greater than
required by the type. [...]" -- 5.2.4.2.2p9

So: The computations involving the `float' numbers you generate
might come out differently on different machines, even if you
manage to generate exactly the same `float' numbers. One machine
could use `float' precision, another could use `double', yet
another might use `long double' or even some hardware-internal
precision not directly accessible from C. The upshot is that a
low-order bit might round differently every now and again. (And
because of the way your program operates, there's a decent chance
that the damage could be affect only a single block and leave any
subsequent blocks intact.)

I'm not saying this *does* happen, only that it might. Unless
you find some other smoking gun -- or even if you do! -- I'd suggest
eliminating all floating-point calculation from the program. Use
a purely-integer PRNG, and use purely-integer arithmetic on what
it generates.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d
 
Reply With Quote
 
 
 
 
Mikko Rauhala
Guest
Posts: n/a
 
      01-10-2014
On Fri, 10 Jan 2014 17:54:12 -0500, Eric Sosman
<(E-Mail Removed)> wrote:
> On 1/10/2014 5:05 AM, JohnF wrote:
>> I'm getting a tiny-cum-microscopic, but nevertheless fatal,
>> difference in the behavior of the exact same C code compiled
>> on one 64-bit linux machine...

>
> I concur with Ben Bacarisse's assessment of the code's
> readability; my head hurts, too! But I toughed it out with
> Tylenol long enough to notice one possible source of trouble:
> Your pseudo-random number generator produces `float' values.


Good catch. This is definitely something that might cause the
problem. To add some detail, x86 FPUs use 80-bit extended
precision internally, while x86-64 has deprecated (or altogether
disabled for long mode, not sure) the old FPU interface. x86-64
compilers use SSE2 as the baseline for float functionality these
days, and _there_ the precision is standard 64-bit double.

--
Mikko Rauhala - (E-Mail Removed) - <URL:http://www.iki.fi/mjr/>
 
Reply With Quote
 
 
 
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      01-10-2014
Eric Sosman <(E-Mail Removed)> wrote:
> On 1/10/2014 5:05 AM, JohnF wrote:
>> I'm getting a tiny-cum-microscopic, but nevertheless fatal,
>> difference in the behavior of the exact same C code compiled
>> on one 64-bit linux machine...


> I concur with Ben Bacarisse's assessment of the code's
> readability; my head hurts, too! But I toughed it out with
> Tylenol long enough to notice one possible source of trouble:
> Your pseudo-random number generator produces `float' values.
> Even if the internal mechanics of the generator are accurately
> reproduced on all systems, the actual values used in subsequent
> computations might not be. The C Standard gives implementations
> some freedom in floating-point calculation, in particular:


I hadn't looked at it at all before my post. Yes, don't use float
if you want predictable results. Knuth has written that floating
point shouldn't be used for financial or typesetting. Seems to me
that it shouldn't be used for encryption, either.

The other one that I thought about that comes up just often
enough is bit shifts greater than or equal to the word size.

Many machines treat shift modulo the width of the word, such
that shifting a 32 bit int 32 bits doesn't shift at all.
On a 64 bit system, with a 64 bit int, it would shift.

-- glen
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-11-2014
glen herrmannsfeldt <(E-Mail Removed)> writes:
[...]
> Many machines treat shift modulo the width of the word, such
> that shifting a 32 bit int 32 bits doesn't shift at all.
> On a 64 bit system, with a 64 bit int, it would shift.


Which is why such shifts have undefined behavior (depending on the width
of the left operand, not necessarily on the width of a "word"):

N1570 6.5.7p3:
The integer promotions are performed on each of the operands. The
type of the result is that of the promoted left operand.
If the value of the right operand is negative or is greater
than or equal to the width of the promoted left operand, the
behavior is undefined.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-11-2014
Mikko Rauhala <(E-Mail Removed)> writes:

> On Fri, 10 Jan 2014 17:54:12 -0500, Eric Sosman
> <(E-Mail Removed)> wrote:
>> On 1/10/2014 5:05 AM, JohnF wrote:
>>> I'm getting a tiny-cum-microscopic, but nevertheless fatal,
>>> difference in the behavior of the exact same C code compiled
>>> on one 64-bit linux machine...

>>
>> I concur with Ben Bacarisse's assessment of the code's
>> readability; my head hurts, too! But I toughed it out with
>> Tylenol long enough to notice one possible source of trouble:
>> Your pseudo-random number generator produces `float' values.

>
> Good catch. This is definitely something that might cause the
> problem.


Yes, good spot. It might not be a problem though because the program
scatters "random" data about which is then filtered out on decryption.
FP differences will just add another dimension to the "randomness".
However, if the RNG is also used for deterministic but chaotic data in
the heart of the algorithm then, yes, there will be trouble ahead.

<snip>
--
Ben.
 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      01-11-2014
Keith Thompson <(E-Mail Removed)> wrote:
> glen herrmannsfeldt <(E-Mail Removed)> writes:
> [...]
>> Many machines treat shift modulo the width of the word, such
>> that shifting a 32 bit int 32 bits doesn't shift at all.
>> On a 64 bit system, with a 64 bit int, it would shift.


> Which is why such shifts have undefined behavior (depending on the width
> of the left operand, not necessarily on the width of a "word"):


If you define "word" as the size of the left operand, then it is word,
but yes. Well, after the appropriate promotions.

> N1570 6.5.7p3:
> The integer promotions are performed on each of the operands. The
> type of the result is that of the promoted left operand.
> If the value of the right operand is negative or is greater
> than or equal to the width of the promoted left operand, the
> behavior is undefined.


In the development of the Hercules IBM mainframe emulator, when
OS/360 was almost, but not quite, running, I remembered that S/360
does shifts (32 and 64 bit) modulo 64. As well as I remember, without
looking at the code I figured out that might be a problem.

-- glen

-- glen
 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      01-11-2014
On 2014-01-11, glen herrmannsfeldt <(E-Mail Removed)> wrote:
> Keith Thompson <(E-Mail Removed)> wrote:
>> glen herrmannsfeldt <(E-Mail Removed)> writes:
>> [...]
>>> Many machines treat shift modulo the width of the word, such
>>> that shifting a 32 bit int 32 bits doesn't shift at all.
>>> On a 64 bit system, with a 64 bit int, it would shift.

>
>> Which is why such shifts have undefined behavior (depending on the width
>> of the left operand, not necessarily on the width of a "word"):

>
> If you define "word" as the size of the left operand, then it is word,
> but yes. Well, after the appropriate promotions.
>
>> N1570 6.5.7p3:
>> The integer promotions are performed on each of the operands. The
>> type of the result is that of the promoted left operand.
>> If the value of the right operand is negative or is greater
>> than or equal to the width of the promoted left operand, the
>> behavior is undefined.

>
> In the development of the Hercules IBM mainframe emulator, when
> OS/360 was almost, but not quite, running, I remembered that S/360
> does shifts (32 and 64 bit) modulo 64. As well as I remember, without
> looking at the code I figured out that might be a problem.


Other undefined behaviors can happen "modulo". For instance, suppose that a
structure contains some small near the beginning and so statically addressed
entries in this array, like foo.a[3] can be addressed using some displaced
addressing mode where the displacement is a small field in the instruction
opcode, say 6 bits wide or whatever. Then foo.a[257] could be reduced to 1
(modulo 64): just stuffed into the opcode and truncated. "Undefined behavior"
allows that.
 
Reply With Quote
 
JohnF
Guest
Posts: n/a
 
      01-11-2014
James Kuyper <(E-Mail Removed)> wrote:
> On 01/10/2014 08:21 AM, JohnF wrote:
>> glen herrmannsfeldt <(E-Mail Removed)> wrote:
>>> JohnF <(E-Mail Removed)> wrote:

>
>> For encrypting, the program fread()'s the input file in randomly-sized
>> blocks, processing each block separately. It first adds a random number
>> of noise bytes (which can be set to 0 and which I tried),
>> then randomly xor or xnor's each data byte with a random byte from
>> your key, and finally randomly permutes the bits of the entire block
>> (typically a many-thousand-bit permutation). Decrypting reverses
>> the procedure.

> ...
>> Of course, I can modify the program to turn off stuff more
>> "slowly", and I'm pretty sure that'll eventually zero in on the
>> problem. But it's a big pain to do that properly, e.g., the random
>> number streams have to be kept in sync reversibly, so that
>> encrypted stuff can be decrypted.

>
> The random numbers in your program make it difficult to debug, because
> the behavior can be different each time it's run.


Not really. Seeds are generated from hash-like functions of user's
input key(s). How could it later decrypt what it had previously
encrypted if seeds were generated differently every run?
But I did find the problem (see subsequent followup),
and you're closer than you might think based on preceding remark.

> For debugging
> purposes, you should modify the code to use a fixed seed for your random
> number generator, so that it generates exactly the same random numbers
> each time it is run. Make sure that the particular seed you use is one
> that will reproduce the problem!
> One possible issue is that the random number generators on the two
> systems might be different. You might need to write your own, just to
> make sure it generates the same sequence every time, on both systems. It
> doesn't have to be a very sophisticated one, so long as it does
> reproducibly duplicate the problem you're seeing.

--
John Forkosh ( mailto: (E-Mail Removed) where j=john and f=forkosh )
 
Reply With Quote
 
JohnF
Guest
Posts: n/a
 
      01-11-2014
BartC <(E-Mail Removed)> wrote:
> "JohnF" <(E-Mail Removed)> wrote in message
> news:laoua0$r0m$(E-Mail Removed)...
>> BartC <(E-Mail Removed)> wrote:
>>> "JohnF" <(E-Mail Removed)> wrote in message

>
>>> You might try also using, temporarily, specific widths for all integers,
>>> instead of relying on whatever width 'int' happens to map to. However, if
>>> int is 64-bits on one machine, then I think all intermediate results will
>>> be
>>> widened to 64-bits, whatever you do.)

>>
>> Yeah, I didn't mention that I'd also tried -m32-bit on the 64-bit box,
>> but that compiler (--version is cc (Debian 4.3.2-1.1) 4.3.2) said
>> cc1: error: unrecognized command line option "-m32-bit"
>> and man cc isn't on that machine.

>
> How big are int, long and long long on your machines?


Yeah, I suppose I should put a verbose/debugging printf
for sizeof(this),sizeof(that),sizeof(the_other_thing), etc,
just to easily and immediately see what's going on in
every environment I run it on.

> I seem to remember that gcc 'long' was 32-bit under Windows, and 64-bit
> under Linux. (If you expect long to be 64-bits, and ever want to run under
> Windows, you might want to upgrade the type.)
>
> (I've looked at your code; I've no idea what the problem might be, but if
> you're porting from an int=32, long=64 implementation to an int=64, long=64
> one, I'm surprised you haven't got bigger differences. Certainly my own code
> would have a load of problems!)


The code's supposed to be portable, and not care as long as int>=32.
The one place it wanted strictly >32 I used long long (despite
obnoxious -Wall warnings about it). Anyway, I found the problem,
explained in subsequent followup, kind of along the lines you're
suggesting, but a rounding problem.
--
John Forkosh ( mailto: (E-Mail Removed) where j=john and f=forkosh )
 
Reply With Quote
 
Werner Wenzel
Guest
Posts: n/a
 
      01-11-2014
Am 11.01.2014 01:06, schrieb Keith Thompson:
> N1570 6.5.7p3:


Please tell a non-native speaker what "p" in "6.5.7p3" stands for:

"point"? "phrase"?

Assuming that if refers to the number on the margin I would call it
"margin number", "marginal number", or "recital".

Thanks in advance.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is the point of having 16 bit colour if a computer monitor can only display 8 bit colour? How do you edit 16 bit colour when you can only see 8 bit? Scotius Digital Photography 6 07-13-2010 03:33 AM
DEVELOP THE WINNING EDGE, SMALL DIFFERENCES IN YOUR PERFORMANCE CANLEAD TO LARGE DIFFERENCES IN YOUR RESULTS Home_Job_opportunity C Programming 0 01-14-2009 03:51 PM
DEVELOP THE WINNING EDGE, SMALL DIFFERENCES IN YOUR PERFORMANCE CANLEAD TO LARGE DIFFERENCES IN YOUR RESULTS Home_Job_opportunity C Programming 0 01-08-2009 04:31 PM
64 bit - Windows Liberty 64bit, Windows Limited Edition 64 Bit, Microsoft SQL Server 2000 Developer Edition 64 Bit, IBM DB2 64 bit - new ! vvcd Computer Support 0 09-17-2004 08:15 PM
64 bit - Windows Liberty 64bit, Windows Limited Edition 64 Bit,Microsoft SQL Server 2000 Developer Edition 64 Bit, IBM DB2 64 bit - new! Ionizer Computer Support 1 01-01-2004 07:27 PM



Advertisments