Бенч неправильный для современных процов с их конвейерами. Одно сложение в цикле и сразу проверка на выход. Да, во втором случае есть еще одна на overflow, как видно из objdump, но её видать съедает предсказатель переходов или еще какой микрокодовый гремлин. :)
Интереснее так:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define unlikely(x) __builtin_expect(!!(x), 0)int main(int argc, char **argv) {
int i = 0, j=0,k=0,l=0, add1 = atoi(argv[2]), add2 = atoi(argv[3]), add3 = atoi(argv[4]), add4 = atoi(argv[5]), max = atoi(argv[6]);
printf("int max %d\n", INT_MAX);
if (*argv[1] != 'c') {
puts("unchecked");
while (i < max) {
i += add1;
j += add2;
k += add3;
l += add4;
}
} else {
puts("checked\n");
while (i < max) {
int of = __builtin_add_overflow(i, add1, &i);
if (unlikely(of)) {
if (of)
puts("overflow detected!!1\n");
break;
}
int ofj = __builtin_add_overflow(j, add2, &j);
if (unlikely(ofj)) {
if (ofj)
puts("overflow detected!!1\n");
break;
}
int ofk = __builtin_add_overflow(k, add3, &k);
if (unlikely(ofk)) {
if (ofk)
puts("overflow detected!!1\n");
break;
}
int ofl = __builtin_add_overflow(l, add4, &l);
if (unlikely(ofl)) {
if (ofl)
puts("overflow detected!!1\n");
break;
}
}
}
printf("i = %d\n", i);
printf("j = %d\n", j);
printf("k = %d\n", k);
printf("l = %d\n", l);
return 0;
}
time ./a.out u 1 1 1 1 2147483647
int max 2147483647
unchecked
i = 2147483647
j = 2147483647
k = 2147483647
l = 2147483647
real 0m0,745s
user 0m0,745s
sys 0m0,000s
time ./a.out c 1 1 1 1 2147483647
int max 2147483647
checked
i = 2147483647
j = 2147483647
k = 2147483647
l = 2147483647
real 0m1,326s
user 0m1,326s
sys 0m0,000s
Оно и неудивительно, ведь в непроверяемом варианте gcc нагенерил:
d0: 01 da add edx,ebx
j += add2;
d2: 41 01 ec add r12d,ebp
k += add3;
d5: 45 01 f5 add r13d,r14d
l += add4;
d8: 45 01 f8 add r8d,r15d
while (i < max) {
db: 39 ca cmp edx,ecx
dd: 7c f1 jl d0 <main+0xd0>
А в проверяемом:
16e: 39 d1 cmp ecx,edx
170: 0f 8e 69 ff ff ff jle df <main+0xdf>
176: 01 da add edx,ebx
178: 70 0f jo 189 <main+0x189>
17a: 41 01 ec add r12d,ebp
17d: 70 0a jo 189 <main+0x189>
17f: 45 01 f5 add r13d,r14d
182: 70 05 jo 189 <main+0x189>
184: 45 01 f8 add r8d,r15d
187: 71 e5 jno 16e <main+0x16e>