c++ - Replacing IF statement (random condition) with boolean logic- execution time identical? -
(setup: win 7 64, msvc, 3rd generation core i7, 64-bit compliation, -o2 enabled)
the below code has 3 functions- 1 has if statement executes different code depending on whether condition has been met. replaced if statement boolean logic. timings identical.... expecting lack of branch prediction yield faster code:
#include <iostream> unsigned long long iterations = 1000000000; void test1(){ volatile int c = 0; for(int i=0; i<iterations; i++){ bool condition = __rdtsc() % 2 == 0; if(condition){ c = 4; } else{ c = 5; } } } void test2(){ volatile int c = 0; for(int i=0; i<iterations; i++){ bool condition = __rdtsc() % 2 == 0; c = (4 * condition) + (5 * !condition); } } int main(){ unsigned long long s = 0; unsigned long long f = 0; unsigned long long s2 = 0; unsigned long long f2 = 0; unsigned int x = 0; unsigned int y = 0; start = __rdtscp(&x); test1(); finish = __rdtscp(&y); start2 = __rdtscp(&x); test2(); finish2 = __rdtscp(&y); std::cout << "1: " << f - s<< std::endl; std::cout << "2: " << f2- s2<< std::endl; }
update asm:
int main(){ push rbp push rsi push rdi push r14 sub rsp,20h unsigned long long start = 0; unsigned long long finish = 0; unsigned long long start2 = 0; unsigned long long finish2 = 0; unsigned long long start3 = 0; unsigned long long finish3 = 0; unsigned int x = 0; xor r8d,r8d mov dword ptr [x],r8d unsigned int y = 0; mov dword ptr [y],r8d start = __rdtscp(&x); rdtscp lea r9,[x] shl rdx,20h mov dword ptr [r9],ecx or rax,rdx test1(); mov dword ptr [rsp+60h],r8d mov ecx,r8d start = __rdtscp(&x); mov r10,rax nop word ptr [rax+rax] test1(); rdtsc shl rdx,20h or rax,rdx xor al,0ffh , al,1 neg al sbb eax,eax inc ecx add eax,5 mov dword ptr [rsp+60h],eax movsxd rax,ecx cmp rax,3e8h test1(); jb main+40h (013ffe1280h) finish = __rdtscp(&y); rdtscp lea r9,[y] shl rdx,20h or rax,rdx mov dword ptr [r9],ecx mov rbp,rax start2 = __rdtscp(&x); rdtscp lea r9,[x] shl rdx,20h mov dword ptr [r9],ecx or rax,rdx test2(); mov dword ptr [rsp+60h],r8d mov r9d,r8d start2 = __rdtscp(&x); mov r14,rax nop word ptr [rax+rax] test2(); rdtsc shl rdx,20h inc r9d or rax,rdx xor al,0ffh , al,1 test2(); movzx ecx,al lea eax,[rcx+rcx*8] mov dword ptr [rsp+60h],eax movsxd rax,r9d cmp rax,3e8h jb main+0a0h (013ffe12e0h) finish2 = __rdtscp(&y);
the generated code doesn't contain internal branches either function, why there no mis-prediction penalty.
in first 1 converts boolean either 0 or -1 (around sbb eax,eax
) , adds 5. pretty standard optimisation when working booleans.
in second 1 multiplies 9 (rcx+rcx*8
), because have 5 * condition
not 5 * !condition
.
Comments
Post a Comment