我根据收到的意见重新提出这个问题。
我有一个运行了30亿次的循环,并将值分配给使用malloc()分配的一块内存;
当循环包含一个条件时,它的运行速度比条件不存在时要慢得多。查看以下方案:
情景A:条件存在且程序缓慢(43秒)
场景B:条件不存在且程序更快(4秒)
// gcc -O3 -c block.c && gcc -o block block.o
#include <stdio.h>
#include <stdlib.h>
#define LEN 3000000000
int main (int argc, char** argv){
long i,j;
unsigned char *n = NULL;
unsigned char *m = NULL;
m = (unsigned char *) malloc (sizeof(char) * LEN);
n = m;
srand ((unsigned) time(NULL));
int t = (unsigned) time(NULL);
for (j = 0; j < 10; j++){
n = m;
for (i = 0; i < LEN; i++){
//////////// A: THIS IS SLOW
/*
if (i % 2){
*n = 1;
} else {
*n = 0;
}
*/
/////////// END OF A
/////////// B: THIS IS FAST
*n = 0;
i % 2;
*n = 1;
/////////// END OF B
n += 1;
}
}
printf("Done. %d sec \n", ((unsigned) time(NULL)) - t );
free(m);
return 0;
}
此致 KD
答案 0 :(得分:1)
您可以使用gcc -S -O3查看生成的汇编程序。 以下是英特尔盒子上的示例:
快速版:
movl %eax, %r12d
.p2align 4,,10
.p2align 3
.L2:
movl $3000000000, %edx
movl $1, %esi
movq %rbp, %rdi
call memset
subq $1, %rbx
jne .L2
慢版:
movl $10, %edi
movl %eax, %ebp
movl $3000000000, %esi
.p2align 4,,10
.p2align 3
.L2:
xorl %edx, %edx
.p2align 4,,10
.p2align 3
.L5:
movq %rdx, %rcx
andl $1, %ecx
movb %cl, (%rbx,%rdx)
addq $1, %rdx
cmpq %rsi, %rdx
jne .L5
subq $1, %rdi
jne .L2
结论:编译器比你想象的更聪明。它能够将内部循环优化为memset(由于它在Intel上使用SSE / AVX或REP指令,因此速度更快)。但是,如果保持条件,则无法启动此优化 - 因为结果不同。