[英]Threads failing to affect performance
下面是一个小程序,用于并行化1 /(n ^ 2)级数的逼近。 注意全局参数NUM_THREADS
。
我的问题是,将线程数从1增加到4(计算机拥有的处理器数量是4)不会显着影响时序实验的结果。 您是否在ThreadFunction
看到逻辑缺陷? 是否存在错误的共享或放错位置的阻止,最终导致执行序列化?
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <string>
#include <future>
#include <chrono>
std::mutex sum_mutex; // This mutex is for the sum vector
std::vector<double> sum_vec; // This is the sum vector
int NUM_THREADS = 1;
int UPPER_BD = 1000000;
/* Thread function */
void ThreadFunction(std::vector<double> &l, int beg, int end, int thread_num)
{
double sum = 0;
for(int i = beg; i < end; i++) sum += (1 / ( l[i] * l[i]) );
std::unique_lock<std::mutex> lock1 (sum_mutex, std::defer_lock);
lock1.lock();
sum_vec.push_back(sum);
lock1.unlock();
}
void ListFill(std::vector<double> &l, int z)
{
for(int i = 0; i < z; ++i) l.push_back(i);
}
int main()
{
std::vector<double> l;
std::vector<std::thread> thread_vec;
ListFill(l, UPPER_BD);
int len = l.size();
int lower_bd = 1;
int increment = (UPPER_BD - lower_bd) / NUM_THREADS;
for (int j = 0; j < NUM_THREADS; ++j)
{
thread_vec.push_back(std::thread(ThreadFunction, std::ref(l), lower_bd, lower_bd + increment, j));
lower_bd += increment;
}
for (auto &t : thread_vec) t.join();
double big_sum;
for (double z : sum_vec) big_sum += z;
std::cout << big_sum << std::endl;
return 0;
}
通过查看您的代码,我怀疑ListFill比ThreadFunction花费的时间更长。 为什么将值列表传递给线程,而不是将每个线程应循环通过的界限传递给线程? 就像是:
void ThreadFunction( int beg, int end ) {
double sum = 0.0;
for(double i = beg; i < end; i++)
sum += (1.0 / ( i * i) );
std::unique_lock<std::mutex> lock1 (sum_mutex);
sum_vec.push_back(sum);
}
为了最大化并行性,您需要将尽可能多的工作推到线程上。 见阿姆达尔定律
除了dohashi的出色改进之外,您还可以通过预先在主线程中填充sum_vec
来消除对互斥锁的需要:
sum_vec.resize(4);
然后直接在ThreadFunction
写入:
sum_vec[thread_num] = sum;
由于每个线程都写入一个不同的元素,并且不修改向量本身,因此无需锁定任何内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.