El MOV de @Can x86 realmente es "gratis"? ¿Por qué no puedo reproducir esto en absoluto?

Sigo viendo que la gente dice que la instrucción MOV puede ser gratuita en x86, debido al cambio de nombre del registro.

Por mi vida, no puedo verificar esto en un solo caso de prueba. Cada caso de prueba que intento lo desacredita.

Por ejemplo, aquí está el código que estoy compilando con Visual C ++:

#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);
}

Esto produce el siguiente código de ensamblaje para el bucle (siéntase libre de producir esto como desee; obviamente no necesita Visual C ++):

LOOP:
    add edi,esi
    mov ebx,esi
    inc esi
    cmp esi,FFFFFFFFh
    jc  LOOP

Ahora ejecuto este programa varias veces, y observo una diferencia bastante consistente del 2% cuando se elimina la instrucción 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

Entonces, ¿qué da? ¿Por qué el MOV no es "gratis"? ¿Es este ciclo demasiado complicado para x86?
Hay unsolter ¿Ejemplo que puede demostrar que MOV es gratis como la gente dice?
Si es así, ¿qué es? Y si no, ¿por qué todos dicen que MOV es gratis?

Respuestas a la pregunta(2)

Su respuesta a la pregunta