забавный код на C
Sep. 7th, 2001 07:26 pmЭту запись имеет смысл читать только тем, кто знает язык программирования C.
Мне его выдал форчун, уже не в первый раз, и я решил на этот раз записать. Если вам
нечего делать, разгадывайте, что делает этот код с 32-битным числом n:
Update:
37 нашёл отличную ссылку по теме.
Мне его выдал форчун, уже не в первый раз, и я решил на этот раз записать. Если вам
нечего делать, разгадывайте, что делает этот код с 32-битным числом n:
n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
Update:
no subject
Date: 2001-09-07 08:25 pm (UTC)no subject
Date: 2001-09-07 10:26 pm (UTC)Reason is that for branches Intel (and generally all modern CPUs) takes a performance penalty due to pipeline stalls and flushes. Also in your main
loop there is 1 instruction between branches where as potentially Intel can execute several instructions simultaneosly.
As for assembly from avva's code, it's linear and the only possible problem I see with it is that on Pentium IV shifts are slower and have higher latency than ALU operations. But then, there is 7 assembly shifts in his variant and 16 in yours.
You are right in a sense that this all is mostly compiler problem. Given your code I don't see any reason why compiler shouldn't be able to generate code which executes at most 2-3 times slower than
original tricky implementation.
no subject
Date: 2001-09-08 06:24 am (UTC)n1 |= (n & 0x800000000) >> 31;
.....
È ýòîò îãðîìíûé (è â àññåáëåðå as well) êîä âûïîëíÿëñÿ âñåãî â 2.5 ðàçà ìåäëåííåå, ÷åì êîä àââû, è íàìíîãî áûñòðåå ÷åì åñëè èñïîëüçîâàòü êîìàíäû òèïà
if(n & 0x800000000) n1 |= 0x00000001;
 ïîíåäåëüíèê ïîïðîáóþ ðàäè èíòåðåñà íà íåñêîëüêèõ äðóãèõ òèïàõ ïðîöåññîðîâ.
Çà ñèì ïðîùàþñü, èáî è òàê íàïëîäèë óæå íåèìîâåðíîå êîëè÷åñòâî òåêñòà â ÷óæîì æóðíàëå.