Я тут имел реальную ситуацию, которая может примерно оценить некоторые параметры при сравнении x86 и ARM. Я делал частную изменённую реализацию математики RIPEMD сначала на х86, а потом на ARM. Обе для получения максимальной скорости на ассмеблере. Вот, например, один из раундов:
Код:
ecx := Rol9( (ecx + PDWord(@HashBuf[0])^) + (((eax xor ebx) and edx) xor ebx) );
1: add ecx,dword ptr NEWHASH[0]
2: mov esi,eax
3: xor esi,ebx
4: and esi,edx
5: xor esi,ebx
6: add ecx,esi
7: rol ecx,$00000009
1: EOR R8, R0, R1
2: AND R8, R8, R3
3: EOR R8, R8, R1
4: ADD R8, R8, R4
5: ADD R2, R2, R8
6: ROR R2, R2, #23
Видно, что ARM имеет достаточно регистров, чтобы поместить в них все необходимые переменные (это два набора по 128 бит, + 64 бита исходные данные + пара регистров на времянку), а у x86 кое-что (исходные данные) приходится оставлять в памяти. Так же тройная адресация ARM экономит как минимум 1 инструкцию (далее есть раунды где экономится 2 инструкции). В итоге, пиковая производительность счёта в коротком цикле составляет примерно 10MH/s на 3GHz в одном потоке для х86 (пробовал и Pentium D и на Core i7 - одинаково) и примерно 330kH/s в одном потоке на ARM CortexM4 168MHz (STM32F4xx). Получается, что у первого 300 хэшей на 1 МГц, а у второго всего ~1,964. Длину получаемого кода не сравнивал, у ARM включен палец. Было бы интересно проверить на более мощных ARMv7+, которые умеют в гигагерцы, чтобы быть в одинаковой позиции хотя-бы по тактовой частоте.
PS Чтобы быть честным, то реализация этого алгоритма на паскале или С (первая строчка в тэге код) даёт пиковую производительность в 150-200кH/s, что даже ниже чем у контроллера. Именно перепись на ассемблер дало такой громадный скачок. Правда, какие-то ключи оптимизации компиляторов я не пробовал, но не думаю, что там будет быстрее, чем 800к. Есть мнение, что вся процедурка (а это порядка 300 инструкций) тупо поместилась в кэше процессора отсюда и такой аномальный буст. Вот так вот.
PPS Вот еще один раунд с другой математикой:
Код:
eax := Rol7( (eax+$5A827999) + (((ecx or edx) and ebx) or (ecx and edx)) );
1: add eax,$5A827999
2: mov esi,ecx
3: mov edi,ecx
4: or esi,edx
5: and esi,ebx
6: and edi,edx
7: or edi,esi
8: add eax,edi
9: rol eax,$00000007
1: ORR R8, R2, R3
2: AND R8, R8, R1
3: AND R9, R2, R3
4: ORR R8, R8, R9
5: ADD R8, R8, R6
6: ADD R0, R0, R8
7: ROR R0, R0, #25
Всё-таки тройная адресация по любому рулит.