Якщо натиснути "Open in Compiler Explorer" (перехід на Godbolt), то вилазить такий код для тестових циклів цих двох варіантів:
.LBB0_3:                                # =>This Inner Loop Header: Depth=1
        add     qword ptr [rsp + 8], 1
        add     rbx, -1
        jne     .LBB0_3
i
.LBB1_3:                                # =>This Inner Loop Header: Depth=1
        lea     rcx, [rax + 1]
        mov     rax, rcx
        cmp     rbx, rcx
        jne     .LBB1_3
Як бачите, в першому випадку компілятор наполіг на тому, щоб зберегти x як фізично існуючу змінну в пам'яті. А в другому випадку представив її регістром. Звідси й різниця в продуктивності. Я б припустив, що це наслідок того, що результат преінкремента в С++ є lvalue. І цей тестбенч з якоїсь причини наполягає на тому, щоб зберегти lvalue-ність результату. Швидше за все це навіть фіча, тобто документована властивість benchmark::DoNotOptimize, про яку потрібно пам'ятати.
Якщо в першому випадку "допомогти" компілятору зрозуміти, що нам нафіг не потрібна lvalue-ність результату ++x, наприклад за допомогою явного приведення типу
benchmark::DoNotOptimize(std::size_t{++x});
, то результати виходять набагато рівніші за продуктивністю.