Я постоянно вижу, что люди утверждают, что инструкция MOV может быть бесплатной в x86 из-за переименования регистра.
В течение жизни я не могу проверить это в одном тестовом случае. Каждый тестовый пример, который я пробовал, развенчивает его.
Например, здесь код, который я компилирую с Visual С++:
#include <limits.h>
#include <stdio.h>
#include <time.h>
int main(void)
{
unsigned int k, l, j;
clock_t tstart = clock();
for (k = 0, j = 0, l = 0; j < UINT_MAX; ++j)
{
++k;
k = j; // <-- comment out this line to remove the MOV instruction
l += j;
}
fprintf(stderr, "%d ms\n", (int)((clock() - tstart) * 1000 / CLOCKS_PER_SEC));
fflush(stderr);
return (int)(k + j + l);
}
Это создает следующий код сборки для цикла (не стесняйтесь делать это, как вы хотите, вам явно не нужен Visual С++):
LOOP:
add edi,esi
mov ebx,esi
inc esi
cmp esi,FFFFFFFFh
jc LOOP
Теперь я запускаю эту программу несколько раз, и я наблюдаю довольно последовательную 2-процентную разницу при удалении инструкции MOV:
Without MOV With MOV
1303 ms 1358 ms
1324 ms 1363 ms
1310 ms 1345 ms
1304 ms 1343 ms
1309 ms 1334 ms
1312 ms 1336 ms
1320 ms 1311 ms
1302 ms 1350 ms
1319 ms 1339 ms
1324 ms 1338 ms
Итак, что дает? Почему MOV "свободен"? Этот цикл слишком сложный для x86?
Есть ли один пример, который может продемонстрировать, что MOV свободен, как утверждают люди?
Если так, то, что это? А если нет, то почему все продолжают требовать, чтобы MOV был бесплатным?