多线程 - 效率降低,可能由“虚假共享”引起

时间:2017-04-23 13:18:13

标签: c++ multithreading false-sharing

我需要计算两个使用相同参数的不同函数(仅用于读取)。我使程序多线程后,程序运行需要2倍的时间(而不是0.5倍)。我是多线程编程的新手,但我怀疑是false sharing

我的原始代码(剪切):

#include <iostream>

double frac_twins(double mu, double sigma,p){
    return 1;
}
double dist_twins(double mu, double sigma,p){
    return 2;
}

int main(){

int n_t=100;

double* num_t = new double[n_t];
double* dist_t = new double[n_t];

double mu=2; double sigma=1;
double num,dist;

for(double p=0.001; p<=0.101;p+=0.001){

    num=frac_twins(mu,sigma,p);
    dist=dist_twins(mu,sigma,p);

      num_t[i]=num;
      dist_t[i]=dist;
      i++;
}

return 0;
}

工作正常。然后我尝试使用线程:

#include <iostream>
#include <thread>

double frac_twins(double mu, double sigma,p){
    return 1;
}
double dist_twins(double mu, double sigma,p){
    return 2;
}

int main(){

int n_t=100;

double* num_t = new double[n_t];
double* dist_t = new double[n_t];

double mu=2; double sigma=1;
double num,dist;

for(double p=0.001; p<=0.101;p+=0.001){

      std::thread t1([&num,mu,sigma,p](){
    num=frac_twins(mu,sigma,p);
      });
      std::thread t2([&dist,mu,sigma,p](){
    dist=dist_twins(mu,sigma,p);
      });

      t1.join();
      t2.join();

      num_t[i]=num;
      dist_t[i]=dist;
      i++;
}

return 0;
}

哪个有效,但速度慢2倍。然后我试图'释放'变量'mu,sigma和p',但它仍然慢2倍:

#include <iostream>
#include <thread>

double frac_twins(double mu, double sigma,p){
    return 1;
}
double dist_twins(double mu, double sigma,p){
    return 2;
}

int main(){

int n_t=100;

double* num_t = new double[n_t];
double* dist_t = new double[n_t];

double mu=2; double sigma=1;
double mu2=2; double sigma2=1; double p2;

double num,dist;

for(double p=0.001; p<=0.101;p+=0.001){

      std::thread t1([&num,mu,sigma,p](){
    num=frac_twins(mu,sigma,p);
      });
      mu2=mu; sigma2=sigma; p2=p;
      std::thread t2([&dist,mu2,sigma2,p2](){
    dist=dist_twins(mu,sigma,p);
      });

      t1.join();
      t2.join();

      num_t[i]=num;
      dist_t[i]=dist;
      i++;
}

return 0;
}

1 个答案:

答案 0 :(得分:1)

您在线程中调用的函数执行的工作很少,启动这些线程的成本超过了使用多个线程所获得的收益。虚假分享与此毫无关系。

由于musigmap是按值传递的,因此可以在两个线程之间共享(并且无论如何,它们都作为lambda函数的一部分进行复制)开销)。