【发布时间】:2013-01-07 18:36:48
【问题描述】:
我刚刚写了一个程序来测试CPU缓存对速度性能的影响。
void* foo(void* ptr)
{
int* r = (int*) ptr;
for (int i = (r - s); i < N; i += NUM_THREADS)
*r += num[i];
return NULL;
}
void* bar(void* ptr)
{
int* r = (int*) ptr;
int idx = r - s;
int block = N/NUM_THREADS;
int start = idx * block, end = start + block;
for (int i = start; i < end; ++i)
*r += num[i];
return NULL;
}
基本上,foo() 进行隔行扫描,另一方面,bar() 逐块扫描数组。
测试结果表明bar()要快很多:
gcc ping-pong.c -std=gnu99 -lpthread -O2 ; ./a.out
1.077037s
0.395525s
那么如何解释这个结果呢?
完整源代码在:https://gist.github.com/4617935
更新:删除所有 if 语句
【问题讨论】:
-
那个 if 语句看起来与分支预测器问题的那个惊人地相似。有必要拥有吗?
-
@Rohan 和 @Mysticial,
foo()和bar()在同一个随机数组上运行。 -
顺序内存访问几乎总是优于非顺序访问。我不知道还能说什么。
foo()是非连续的,bar()是连续的。我不确定 if 语句的目的是什么。但是,如果它以接近 50% 的概率随机进入,那么这可能会给分支错误预测的结果添加“噪音”。 -
我只是想做类似@Rohan提到的经典问题,计算数组中大于阈值的元素个数。
标签: c caching optimization pthreads cpu-architecture