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, 13 Mar 2008 18:32:24 GMT

Okay, so this function seems to correctly compute the number of bytes
in the value representation of the object. Remind me, where do we need
it in the rest of LIMITS.cpp again? I.e., what does the patch look
like?

Thanks
Martin


Scott Zhong-2 wrote:
> 
> After going through the logic again:
> 
> iter #	i	byte	structure
> 
> 1		1	0		00000001
> 2		2	0		00000010
> 3		3	0		00000100
> 4		4	0		00001000
> 5		5	0		00010000
> 6		6	0		00100000
> 7		7	0		01000000
> 8		8	0		10000000
> 9		1	1		00000001 00000000
> 10		2	1		00000010 00000000
> 11		3	1		00000100 00000000
> 12		4	1		00001000 00000000
> 13		5	1		00010000 00000000
> 14		6	1		00100000 00000000
> 15		7	1		01000000 00000000
> 16		8	1		10000000 00000000
> 17		1	2		00000001 00000000 00000000
> 
> Byte should be initialized to 1.
> 
> template <class T>
> unsigned compute_byte_size()
> {
>     T max = T (one);
>     T current = T(one);
>     unsigned byte = 1;
>     for (int i = 1; T (current * 2) > max; current *=2, max *= 2, i++) {
>         if (i > 8) { byte++; i=1; }
>     }
>     return byte;
> }
> 
>> -----Original Message-----
>> From: Martin Sebor [mailto:sebor@roguewave.com]
>> Sent: Wednesday, March 05, 2008 5:19 PM
>> To: dev@stdcxx.apache.org
>> Subject: Re: [PATCH] STDCXX-423
>> 
>> 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
>> >
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/-PATCH--STDCXX-423-tp15191643p16035049.html
Sent from the stdcxx-dev mailing list archive at Nabble.com.


Mime
View raw message