alla mia macchina kroundup32
dà 6.000m giri/sec
E la prossima funzione fornisce turni 7.693m/sec
inline int scan_msb(int x)
{
#if defined(__i386__) || defined(__x86_64__)
int y;
__asm__("bsr %1, %0"
: "=r" (y)
: "r" (x)
: "flags"); /* ZF */
return y;
#else
#error "Implement me for your platform"
#endif
}
inline int roundup32(int x)
{
if (x == 0) return x;
else {
const int bit = scan_msb(x);
const int mask = ~((~0) << bit);
if (x & mask) return (1 << (bit+1));
else return (1 << bit);
}
}
Così @thomasrutter profondo del cuore non dire che è "altamente ottimizzato".
e appropriato (solo una parte significativa) di montaggio (per GCC 4.4.4):
kroundup32:
subl $1, %edi
movl %edi, %eax
sarl %eax
orl %edi, %eax
movl %eax, %edx
sarl $2, %edx
orl %eax, %edx
movl %edx, %eax
sarl $4, %eax
orl %edx, %eax
movl %eax, %edx
sarl $8, %edx
orl %eax, %edx
movl %edx, %eax
sarl $16, %eax
orl %edx, %eax
addl $1, %eax
ret
roundup32:
testl %edi, %edi
movl %edi, %eax
je .L6
movl $-1, %edx
bsr %edi, %ecx
sall %cl, %edx
notl %edx
testl %edi, %edx
jne .L10
movl $1, %eax
sall %cl, %eax
.L6:
rep
ret
.L10:
addl $1, %ecx
movl $1, %eax
sall %cl, %eax
ret
Per qualche motivo non hanno trovato adeguata attuazione scan_msb
(come #define scan_msb(x) if (__builtin_constant_p (x)) ...
) entro le intestazioni standart di GCC (solo __TBB_machine_lg
/__TBB_Log2
).
Ottimo, ho capito cosa sta facendo ora. Grazie! – GWW
+1 per chi ha codificato (ottimizzato) e +1 per @thomasrutter per decodificarlo :) – KedarX
Uhm, questo non funzionerebbe solo per 16 bit? –