Сначала я не хотел писать этот ответ после тестирования на x86, но тестирование на sparc Solaris показало, что он имеет прирост производительности по сравнению с «очевидным решением», так что, возможно, он будет кому-то полезен. Я взял его из файла в формате PDF, который прилагается к книге Восторг хакера. Вот оно:
unsigned msec2sec(unsigned n) {
unsigned q, r, t;
n = n + 500;
t = (n >> 7) + (n >> 8) + (n >> 12);
q = (n >> 1) + t + (n >> 15) + (t >> 11) + (t >> 14);
q = q >> 9;
r = n - q*1000;
return q + ((r + 24) >> 10);
}
в отличие от:
unsigned msec2sec_obvious(unsigned n) {
return (n + 500)/1000;
}
На x86 «очевидный алгоритм» преобразуется в добавление 500, а затем длинное умножение на 274877907 с последующим захватом наиболее значимых 32 битов из edx и сдвигом их на 6 бит вправо — так что он превосходит этот код выше без труда (примерно в 5 раз больше производительности разница).
Однако на Solaris/sparc "очевидное" трансформируется в вызов .udiv, что в итоге дает разницу в производительности примерно в 2,5 раза в другом направлении.
person
Andrew Y
schedule
18.08.2009