Ниже приведен отрывок из списка двух последовательностей сборки Pentium. У нас есть внешний цикл, который пытается синхронизировать наши последовательности и выполняет сквозную таблицу, чтобы добраться до этих подпрограмм. Таким образом, внешний вызов каждый раз осуществляется из одного и того же места. Две последовательности отличаются тем, что в первой на одну инструкцию меньше, чем во второй.
Результаты, которые мы получаем на двух машинах Intel, очень разные.
Инструкция CPUID сообщает о семействе, модели и шаге.
Машина 1: Семейство 6, Модель 15 Степпинг 11. CPUZ сообщает "Intel Core 2 Duo E6750"
Инструкции выполняются со статистически одинаковой скоростью.
Машина 2: Семейство 15, Модель 3, Степпинг 3. CPUZ сообщает "Intel Pentium 4"
Первая последовательность занимает примерно 8% больше времени, чем вторая.
Мы просто не можем объяснить увеличение времени. Не должно быть никаких других задержек флагов, предсказания ветвей, проблем с использованием регистров и т. Д. По крайней мере, то, что мы можем сказать.
Кто-нибудь знает, почему выполнение первой последовательности на одной машине занимает больше времени?
Изменить: добавление «XOR PTR ereg, 0» к первой последовательности приводит к совпадению синхронизации со второй на Pentium 4. Любопытно.
Первая последовательность:
00000040 ALUSHIFT_AND_C_V_E LABEL NEAR
00000040 0F B7 04 55 MOVZX EAX, gwr[(SIZEOF WORD) * EDX] ; EAX = 0000000000000000 LLLLLLLLLLLLLLLL
00000000 E
00000048 0F B7 14 4D MOVZX EDX, gwr[(SIZEOF WORD) * ECX] ; EDX = 0000000000000000 RRRRRRRRRRRRRRRR
00000000 E
00000050 23 C2 AND EAX, EDX ; AX = L&R (result)
00000052 A3 00000000 E MOV dvalue, EAX ; Save the temporary ALU/Shifter result
00000057 C3 RET ; Return
Вторая последовательность:
00000060 ALUSHIFT_AND_C_V_NE LABEL NEAR
00000060 0F B7 04 55 MOVZX EAX, gwr[(SIZEOF WORD) * EDX] ; EAX = 0000000000000000 LLLLLLLLLLLLLLLL
00000000 E
00000068 0F B7 14 4D MOVZX EDX, gwr[(SIZEOF WORD) * ECX] ; EDX = 0000000000000000 RRRRRRRRRRRRRRRR
00000000 E
00000070 23 C2 AND EAX, EDX ; AX = L&R (result)
00000072 80 35 00000000 E XOR BYTE PTR ereg, 1 ; E = ~E
01
00000079 A3 00000000 E MOV dvalue, EAX ; Save the temporary ALU/Shifter result
0000007E C3 RET ; Return