386 optimized bitblit code

Niels Möller nisse at lysator.liu.se
Sat Jan 31 21:37:18 CET 2004


Brian Hurt <bhurt at spnz.org> writes:

> /* Note that we use div (/) and mod (%) instead of shifts and ands here.
>  * Every compiler I have ever looked at for systems where ints are a
>  * power of two bits turns the divs and mods into shifts and ands when
>  * any optimization is turned on.  So there is no performance advantage
[...]
>     size_t limit;
[...]
>                 for (idx = 0; idx < (limit % 4); ++idx) {

Note that for signed numbers, limit % 4 is not necessarily equivalent
to limit & 3. IIRC, C99 *requires* round-to-zero semantics for integer
division, rather than round-downwards. This implies that for example

  -1 % 4 == -1 - 4 * (-1/4) == -1 - 4*0 == -1 != 3 == -1 & 3.

With round-downwards semantics, you would instead get

  -1 % 4 == -1 - 4 * (-1/4) == -1 - 4*(-1) == 3

as one might expect.

So a compiler can't easily replace x % 4 with x & 3, if x is a signed
quantity, which means that x % 4 can well be significantly slower. So
be careful that you don't use signed values by mistake. size_t is
usually unsigned, but I'm not sure that it *always* is.

(I think the round-towards-zero is a broken heritage from FORTRAN,
that comes to C99 via Java. Too bad the C comittee couldn't get rid of
it).

Regards,
/Niels


More information about the gmp-devel mailing list