并行计算机代码,当我使用并行代码时,为什么我的计算机没有显示加速?

编辑:为响应OP评论添加了Grand Central Dispatch的详细信息.

虽然这里的其他答案一般都很有用,但问题的具体答案是你不应该使用clock()来比较时间. clock()测量跨线程累加的cpu时间.在核心之间拆分作业时,它至少使用尽可能多的cpu时间(通常由于线程开销而更多).在this页面上搜索clock(),找到“如果进程是多线程的,则添加所有单个进程线程占用的cpu时间”.

只是作业在线程之间分配,所以你需要等待的总时间就少了.你应该使用壁挂时间(挂钟上的时间). OpenMP提供了一个例程omp_get_wtime()来完成它.以下面的例程为例:

#include

#include

#include

#include

int main(int argc,char *argv[]) {

int i,nthreads;

clock_t clock_timer;

double wall_timer;

for (nthreads = 1; nthreads <=8; nthreads++) {

clock_timer = clock();

wall_timer = omp_get_wtime();

#pragma omp parallel for private(i) num_threads(nthreads)

for (i = 0; i < 100000000; i++) cos(i);

printf("%d threads: time on clock() = %.3f,on wall = %.3f\n",\

nthreads,\

(double) (clock() - clock_timer) / CLOCKS_PER_SEC,\

omp_get_wtime() - wall_timer);

}

}

结果是:

1 threads: time on clock() = 0.258,on wall = 0.258

2 threads: time on clock() = 0.256,on wall = 0.129

3 threads: time on clock() = 0.255,on wall = 0.086

4 threads: time on clock() = 0.257,on wall = 0.065

5 threads: time on clock() = 0.255,on wall = 0.051

6 threads: time on clock() = 0.257,on wall = 0.044

7 threads: time on clock() = 0.255,on wall = 0.037

8 threads: time on clock() = 0.256,on wall = 0.033

你可以看到clock()时间没有太大变化.我没有编译指示得到0.254,所以使用openMP和一个线程比没有使用openMP要慢一点,但是每个线程的挂壁时间都会减少.

由于例如计算的部分不平行(见Amdahl’s_law)或不同的线程在同一内存上作战,因此改进并不总是这么好.

编辑:对于Grand Central Dispatch,GCD reference指出,GCD使用gettimeofday作为挂号时间.所以,我创建了一个新的Cocoa App,并且在applicationDidFinishLaunching中我放了:

struct timeval t1,t2;

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

for (int iterations = 1; iterations <= 8; iterations++) {

int stride = 1e8/iterations;

gettimeofday(&t1,0);

dispatch_apply(iterations,queue,^(size_t i) {

for (int j = 0; j < stride; j++) cos(j);

});

gettimeofday(&t2,0);

NSLog(@"%d iterations: on wall = %.3f\n",iterations,\

t2.tv_sec+t2.tv_usec/1e6-(t1.tv_sec+t1.tv_usec/1e6));

}

我在控制台上得到以下结果:

2010-03-10 17:33:43.022 GCDClock[39741:a0f] 1 iterations: on wall = 0.254

2010-03-10 17:33:43.151 GCDClock[39741:a0f] 2 iterations: on wall = 0.127

2010-03-10 17:33:43.236 GCDClock[39741:a0f] 3 iterations: on wall = 0.085

2010-03-10 17:33:43.301 GCDClock[39741:a0f] 4 iterations: on wall = 0.064

2010-03-10 17:33:43.352 GCDClock[39741:a0f] 5 iterations: on wall = 0.051

2010-03-10 17:33:43.395 GCDClock[39741:a0f] 6 iterations: on wall = 0.043

2010-03-10 17:33:43.433 GCDClock[39741:a0f] 7 iterations: on wall = 0.038

2010-03-10 17:33:43.468 GCDClock[39741:a0f] 8 iterations: on wall = 0.034

这与我上面的情况大致相同.

这是一个非常人为的例子.实际上,您需要确保将优化保持在-O0,否则编译器将意识到我们不进行任何计算而根本不进行循环.另外,我在两个例子中使用cos的整数是不同的,但这并不会对结果产生太大影响.有关如何正确执行此操作的信息,请参阅联机帮助页上的STRIDE以及为什么迭代在这种情况下与num_threads大致相当.

编辑:我注意到雅各布的回答包括

I use the omp_get_thread_num()

function within my parallelized loop

to print out which core it’s working

on… This way you can be sure that

it’s running on both cores.

这是不正确的(它已被编辑部分修复).使用omp_get_thread_num()确实是一种确保代码是多线程的好方法,但它没有显示“它正在处理哪个核心”,只是哪个线程.例如,以下代码:

#include

#include

int main() {

int i;

#pragma omp parallel for private(i) num_threads(50)

for (i = 0; i < 50; i++) printf("%d\n",omp_get_thread_num());

}

打印出它使用线程0到49,但这并没有显示它正在处理哪个核心,因为我只有8个核心.通过查看活动监视器(OP提到GCD,因此必须在Mac上 – 进入窗口/ cpu使用率),您可以看到在核心之间切换的作业,因此核心!=线程.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值