Есть ли способ для кода C определить, компилируется ли он в архитектуре, где умножение происходит быстро? Есть ли макрос __FAST_MULT__
или что-то, что определено на этих архитектурах?
Например, предположим, что вы реализуете функцию для определения веса Хэмминга 64-битного целого с помощью метода shift-and-add *. Существуют два оптимальных алгоритма для этого: требуется 17 арифметических операций, а для другого требуется только 12, но одна из них - операция умножения. Второй алгоритм, таким образом, на 30% быстрее, если вы работаете на оборудовании, где умножение занимает такое же количество времени, что и добавление, но гораздо медленнее в системе, где умножение реализуется как повторное добавление. Таким образом, при написании такой функции было бы полезно иметь возможность проверять во время компиляции, является ли это так, и переключаться между двумя алгоритмами, если это необходимо:
unsigned int popcount_64(uint64_t x) {
x -= (x >> 1) & 0x5555555555555555; // put count of each 2 bits into those 2 bits
x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); // put count of each 4 bits into those 4 bits
x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f; // put count of each 8 bits into those 8 bits
#ifdef __FAST_MULT__
return (x * 0x0101010101010101)>>56; // returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
#else // __FAST_MULT__
x += x >> 8; // put count of each 16 bits into their lowest 8 bits
x += x >> 16; // put count of each 32 bits into their lowest 8 bits
x += x >> 32; // put count of each 64 bits into their lowest 8 bits
return x & 0x7f;
#endif // __FAST_MULT__
}
Есть ли способ сделать это?
* Да, я знаю функции __builtin_popcount()
; это просто пример.