Joe Buck wrote:
> > > inline size_t __compute_size(size_t num, size_t size) {
> > >     size_t product = num * size;
> > >     return product >= num ? product : ~size_t(0);
> > > }

2007/4/9, Ross Smith <[EMAIL PROTECTED]> wrote:
On Monday, 9 April 2007 10:23, Florian Weimer wrote:
> * Ross Ridge:
> > Florian Weimer writes:
> >>I don't think this check is correct.  Consider num = 0x33333334 and
> >>size = 6.  It seems that the check is difficult to perform
> >> efficiently unless the architecture provides unsigned
> >> multiplication with overflow detection, or an instruction to
> >> implement __builtin_clz.
> >
> > This should work instead:
> >
> >     inline size_t __compute_size(size_t num, size_t size) {
> >             if (num > ~size_t(0) / size)
> >                     return ~size_t(0);
> >             return num * size;
> >     }
>
> Yeah, but that division is fairly expensive if it can't be performed
> at compile time.  OTOH, if __compute_size is inlined in all places,
> code size does increase somewhat.

You could avoid the division in nearly all cases by checking for
reasonably-sized arguments first:

    inline size_t __compute_size(size_t num, size_t size) {
        static const int max_bits = sizeof(size_t) * CHAR_BITS;
        int low_num, low_size;
        low_num = num < ((size_t)1 << (max_bits * 5 / 8));
        low_size = size < ((size_t)1 << (max_bits * 3 / 8));
        if (__builtin_expect(low_num && low_size, 1)
                || num <= ~(size_t)0 / size)
            return num * size;
        else
            return ~size_t(0);
    }

This code is bigger than Joe Buck's.

I'm sorry, the previous 3rd source code .c is an error mine.

-----------------------------------------

Joe Buck's code: 10 instructions
Ross Ridge's code: 16 instructions
Ross Smith's code: 23 instructions

-----------------------------------------
Joe Buck's code: 9 instructions
__compute_size:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %edx
        movl    %edx, %eax
        imull   12(%ebp), %eax
        cmpl    %edx, %eax
        orl     $-1, %eax
        popl    %ebp
        ret

Ross Ridge's code: 16 instructions
__compute_size:
        pushl   %ebp
        movl    %esp, %ebp
        orl     $-1, %eax
        xorl    %edx, %edx
        movl    12(%ebp), %ecx
        divl    %ecx
        pushl   %ebx
        movl    8(%ebp), %ebx
        orl     $-1, %edx
        cmpl    %eax, %ebx
        movl    %ebx, %edx
        imull   %ecx, %edx
        popl    %ebx
        movl    %edx, %eax
        popl    %ebp
        ret

Ross Smith's code: 23 instructions
__compute_size:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        movl    8(%ebp), %ebx
        cmpl    $1048575, %ebx
        movl    12(%ebp), %ecx
        setbe   %dl
        xorl    %eax, %eax
        cmpl    $4095, %ecx
        setbe   %al
        andb    $1, %dl
        testl   %eax, %eax
        orl     $-1, %eax
        xorl    %edx, %edx
        divl    %ecx
        orl     $-1, %edx
        cmpl    %eax, %ebx
        movl    %ebx, %edx
        imull   %ecx, %edx
        popl    %ebx
        movl    %edx, %eax
        popl    %ebp
        ret

J.C. Pizarro

Reply via email to