linux – 线程实现性能下降

linux – 线程实现性能下降,第1张

概述我在C中实施了一个小程序,使用蒙特卡罗方法计算PI(主要是因为个人兴趣和培训).在实现了基本代码结构之后,我添加了一个命令行选项,允许执行线程计算. 我预计会有很大的加速,但我很失望.命令行概要应该是清楚的.用于近似PI的最终迭代次数是通过命令行传递的-iterations和-threads的乘积. Leaving -threads blank将其默认为1个线程,导致在主线程中执行. 下面的测试总 我在C中实施了一个小程序,使用蒙特卡罗方法计算PI(主要是因为个人兴趣和培训).在实现了基本代码结构之后,我添加了一个命令行选项,允许执行线程计算.

我预计会有很大的加速,但我很失望.命令行概要应该是清楚的.用于近似PI的最终迭代次数是通过命令行传递的-iterations和-threads的乘积. Leaving -threads blank将其默认为1个线程,导致在主线程中执行.

下面的测试总共进行了80万次迭代测试.

在Windows 7 64Bit(Intel Core2Duo Machine)上:

使用Cygwin GCC 4.5.3编译:gcc-4 pi.c -o pi.exe -O3

在Ubuntu / linaro 12.04(8核心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库.在这种情况下如何做正确的澄清将是非常好的.

解决方法 问题是在glibc的实现中,rand()调用 __random(),那就是

long int__random (){  int32_t retval;  __libc_lock_lock (lock);  (voID) __random_r (&unsafe_state,&retval);  __libc_lock_unlock (lock);  return retval;}

锁定每次调用函数__random_r来执行实际工作.

因此,只要您使用rand()有多个线程,就会使每个线程在几乎每次调用rand()时都等待其他线程.在每个线程中直接使用random_r()和自己的缓冲区应该快得多.

总结

以上是内存溢出为你收集整理的linux – 线程实现性能下降全部内容,希望文章能够帮你解决linux – 线程实现性能下降所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/1022029.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存