我不知道您的示例代码与您的应用程序的匹配程度如何,但如果您循环这样的行,您几乎肯定会遇到缓存问题。如果我以行优先和列优先的顺序对循环进行编码,我会看到巨大的性能差异。
使用nrow=1000000
and ncol=1000
,如果我使用array[i][0]
,我会得到大约 1.9 秒的运行时间。如果我使用array[0][i]
,那么它会下降到 0.05 秒。
如果您可以以这种方式转置数据,您应该会看到性能大幅提升。
#ifdef COL_MAJOR
array = (double **)malloc(nrow * sizeof(double *));
for(i=0; i<nrow; i++) {
array[i] = (double *)malloc(ncol * sizeof(double));
array[i][0] = i;
}
for(i=0; i<nrow; i++) {
sum += array[i][0];
}
for(i=0; i<nrow; i++) {
array[i][0] /= sum;
}
#else
array = (double **)malloc(ncol * sizeof(double *));
for(i=0; i<ncol; i++) {
array[i] = (double *)malloc(nrow * sizeof(double));
}
for(i=0; i<nrow; i++) {
array[0][i] = i;
}
for(i=0; i<nrow; i++) {
sum += array[0][i];
}
for(i=0; i<nrow; i++) {
array[0][i] /= sum;
}
#endif
printf("%f\n", sum);
$ gcc -DCOL_MAJOR -O2 -o normed normed.c
$时间./规范
499999500000.000000
真正的 0m1.904s
用户 0m0.325s
系统 0m1.575s
$时间./规范
499999500000.000000
真正的 0m1.874s
用户 0m0.304s
系统 0m1.567s
$时间./规范
499999500000.000000
真实0m1.873s
用户 0m0.296s
系统 0m1.573s
$ gcc -O2 -o normed normed.c
$时间./规范
499999500000.000000
实际0m0.051s
用户 0m0.017s
系统 0m0.024s
$时间./规范
499999500000.000000
实际0m0.050s
用户 0m0.017s
系统 0m0.023s
$时间./规范
499999500000.000000
实际0m0.051s
用户 0m0.014s
系统 0m0.022s
$