Рассмотрим следующий код
typedef unsigned uint;
uint parity( uint64_t x )
{
uint32_t v = x ^ (x >> 32);
v ^= v >> 16;
v ^= v >> 8;
v ^= v >> 4;
v ^= v >> 2;
return (uint)(v ^ (v >> 1)) & 1;
}
Есть ли способ радикальной реорганизации этого кода, чтобы получить серьезное улучшение из-за параллелизма на уровне команд, скажем, на машине Intel x86-64?
GCC произвел следующий код
parity(unsigned long):
mov rax, rdi
shr rax, 32
xor eax, edi
mov edi, eax
shr edi, 16
xor eax, edi
mov edi, eax
shr edi, 8
xor eax, edi
mov edi, eax
shr edi, 4
xor eax, edi
mov edi, eax
shr edi, 2
xor eax, edi
mov edx, eax
shr eax
xor eax, edx
and eax, 1
ret
В 32-битном мире я бы написал прямо на ассемблере что-то вроде test eax,eax
с последующим SETPO EAX
,
ОБНОВЛЕНИЕ 2017-02-06: @EOF верно, команда test устанавливает бит четности только в соответствии с младшим байтом.
Других решений пока нет …