-iterations
和-threads
相乘的结果。将-threads
留空会默认为1
线程,在主线程中执行。下面的测试总共进行了8000万次迭代。
在Windows 7 64位(Intel Core2Duo机器)上:
使用Cygwin GCC 4.5.3编译:gcc-4 pi.c -o pi.exe -O3
在Ubuntu/Linaro 12.04 (8Core AMD)上:
使用GCC 4.6.3编译:gcc pi.c -lm -lpthread -O3 -o pi
性能
在Windows上,使用线程版本比未线程化版本快几毫秒。说实话,我原以为会有更好的表现。在Linux上,呃!怎么回事?为什么要慢2000%?当然这很大程度上取决于实现方式,所以在这里阐述一下。在命令行参数解析完成并开始计算之后的摘录如下:
// Begin computation.
clock_t t_start, t_delta;
double pi = 0;
if (args.threads == 1) {
t_start = clock();
pi = pi_mc(args.iterations);
t_delta = clock() - t_start;
}
else {
pthread_t* threads = malloc(sizeof(pthread_t) * args.threads);
if (!threads) {
return alloc_failed();
}
struct PIThreadData* values = malloc(sizeof(struct PIThreadData) * args.threads);
if (!values) {
free(threads);
return alloc_failed();
}
t_start = clock();
for (i=0; i < args.threads; i++) {
values[i].iterations = args.iterations;
values[i].out = 0.0;
pthread_create(threads + i, NULL, pi_mc_threaded, values + i);
}
for (i=0; i < args.threads; i++) {
pthread_join(threads[i], NULL);
pi += values[i].out;
}
t_delta = clock() - t_start;
free(threads);
threads = NULL;
free(values);
values = NULL;
pi /= (double) args.threads;
}
虽然 pi_mc_threaded()
的实现方式为:
struct PIThreadData {
int iterations;
double out;
};
void* pi_mc_threaded(void* ptr) {
struct PIThreadData* data = ptr;
data->out = pi_mc(data->iterations);
}
你可以在http://pastebin.com/jptBTgwr找到完整的源代码。
问题
为什么会出现这种情况?为什么在Linux上存在如此巨大的差异?我原本期望计算所需的时间至少是原始时间的3/4。当然,可能是我没有正确使用pthread
库。希望能够得到关于在这种情况下正确使用的澄清。