Многопоточность — снижение эффективности, может быть вызвано «ложным разделением»

Мне нужно рассчитать 2 разные функции, которые используют одни и те же параметры (только для чтения). После того, как я сделал программу многопоточной, запуск программы требует 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;
}

0

Решение

Функции, которые вы вызываете в своих потоках, выполняют так мало работы, что стоимость запуска этих потоков превышает выгоду, которую вы получаете, используя несколько потоков. Ложный обмен не имеет к этому никакого отношения.

поскольку mu, sigma, а также p передаются по значению, они могут быть разделены между двумя потоками (и, в любом случае, копируются как часть служебных данных лямбда-функции).

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector