incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: [PATCH] STDCXX-423
Date Thu, 06 Mar 2008 00:19:17 GMT
Scott Zhong wrote:
> 
>> -----Original Message-----
>> From: Martin Sebor [mailto:sebor@roguewave.com]
>> Sent: Wednesday, February 20, 2008 12:26 PM
>> To: dev@stdcxx.apache.org
>> Subject: Re: [PATCH] STDCXX-423
>>
>> Scott Zhong wrote:
>> [...]
>>>>> As I write this, I realize that the my function,
>>> compute_byte_size(),
>>>>> can be optimized to shift one bit to the next byte boundary.
>>>> I don't think we need to (or should) worry about optimizing config
>>>> tests. What we might want to do is use the template parameter in
>>>> the signature of the function for non-conforming compilers that
>>>> have trouble with these types of things.
>>> Sorry I meant to say that its more of a code fix than optimization.
>>> Sizeof() returns the number of bytes so the function should check
> each
>>> byte instead of each bit.
>> But not all bits of every byte need to contribute to the value
>> representation of the object. IIUC, there can be 4 byte ints
>> (i.e., sizeof(int) == 4) with 29 bits for the value, 1 bit for
>> the sign, and 2 bits of padding.
>>
> 
> I had overlooked that fact, thank you for reminding me.
> 
>>>>> template <class T>
>>>>> unsigned compute_byte_size()
>>>>> {
>>>>>     T max = T (one);
>>>>>     unsigned byte = 0;
>>>>>     for (; T (max * 128) > max; max *= 128) {
>>>> FWIW, for signed T the expression T(max * 128) > max has undefined
>>>> behavior in the presence of overflow. We've seen at least two (if
>>>> not three) compilers exploit this presumably in some aggressive
>>>> optimizations (see, for example, STDCXX-482). Since most (all?)
>>>> hardware simply wraps around in the presence of overflow we just
>>>> need to prevent the compiler optimization here.
>>> Would the volatile keyword in front of "max" be sufficient here?
>> It might help, but I'm not sure it's guaranteed to. All it usually
>> does is make the compiler generate code that reloads the value of
>> the object from memory into a register on each access. The stage
>> I'm concerned with takes place before code generation based on what
>> the compiler can prove about the program. For all signed x, the
>> compiler is free to assume that in (x * N) > x, the subexpression
>> (x * N) doesn't overflow and thus (x * N) is always guaranteed to
>> be greater than x (for N > 0). To prevent it from making such an
>> assumption we need to rewrite the expression like so: (x * N) > y
>> while initializing x and y to the same value in such a way that
>> the compiler cannot prove that (x == y) holds.
>>
> 
> Would this suffice?

This doesn't seem correct, not just because of the typo but because
it returns 3 for T = int (assuming one == 1). Even if it was correct
I'm not sure a smart optimizer couldn't make some assumptions about
the dependency between current and max (they are both modified using
exactly the same expression) that would cause the code to misbehave.

Martin

> 
> template <class T>
> unsigned compute_byte_size()
> {
>     T max = T (one);
>     T current = T (one);
>     unsigned byte = 0;
>     for (int I = 1; T (current * 2) > max; current *= 2, max *= 2, i++)
> {
>         if (i > 8 ) {byte++; i = 1; }
>     }
>     return byte;
> }
> 
> 
>> Martin
> 


Mime
View raw message