为什么这种令人尴尬的并行算法的性能没有随着多线程而提高
Why does the performance of this embarrassingly parallel algorithm not improve with multi-threading?
这是我在这里的第一篇文章,尽管我确实定期访问该网站,并在这里找到了很多有价值的信息。
我有一个令人尴尬的并行算法,我希望它能在多线程的情况下显示出巨大的性能改进。
经过大量的阅读和复习,这是我第一次使用多线程。
我使用的是带有VS 2012的C++,我的Windows 7笔记本电脑有一个四核i7处理器和充足的内存。
基本工作分解为这个伪代码
for (int i = 0; i<iMax; i++){
for (int j = 0; j<jMax; j++){
T[j] += E[j][i] * SF;
}
}
T、 E和SF是浮子。
该实现从这里使用了一个(修改后的)线程池。
并从这个函数为线程池构建和添加一组任务
void doWork(float *T, float *E, float SF, int numNodes)
{
// Critical for performance that these loops vectorize.....
for (int nodeCounter = 0; nodeCounter < numNodes; nodeCounter++){
T[nodeCounter] += E[nodeCounter] * SF;
}
};
使用这种结构,
tp.enqueue(std::bind(&doWork, timeStepDisplacements.T1, T1MODE, T1MPF, numNodes));
在我的测试中,numNodes是1000000,我为50个外循环中的每一个调用这个例程3次(使用不同的数组)。我在它的外部还有另一个循环(100),所以我的测试代码生成了这些任务中的15000个,每个任务执行1000000次乘法运算。
编辑:将外循环计数更正为100,任务数从7500更正为15000
当我用8个、16个或更多线程设置线程池时,性能只比串行代码略好——比如8.8秒v's 9.3。
所以我的问题是,为什么性能改进这么小?
注意-如果使用不同的任务例程(下面的work_proc),则相同的线程池设置将显示出巨大的性能提升。
void work_proc()
{
int i = 555;
std::random_device rd;
std::mt19937 rng(rd());
// build a vector of random numbers
std::vector<int> data;
data.reserve(100000);
std::generate_n(std::back_inserter(data), data.capacity(), [&](){ return rng(); });
std::sort(data.begin(), data.end());
}
我发布整个代码没有问题,但我想我应该从这些关键部分开始。
提前Thanx了解所提供的任何见解。
您可能忽略了一些重要的部分,但如果您的伪代码是准确的,那么瓶颈似乎是内存访问。
单核可以以足够快的速度添加数字,从而使DRAM得到充分利用,因此通过拆分这些工作不会获得太多性能。
编辑:如果你知道你的DRAM类型和I/O时钟速率,你可以计算你的DRAM传输速率。这是关于它的速度吗?
例如:15000*1000000在9.3秒内浮动,读取速度为6.4 GB/s。如果你写的量相同,那么就是12.8 GB/s,这是你在评论中所说的DDR3-1600的最大速率。。。
这当然是你的问题。
请注意,您不应该真的需要写入相同的量,因此,如果您将算法重组为更友好的缓存,您可能会使其在您的盒子上的速度几乎是原来的两倍。
如果你让每个工人做4个E,比如:
T[nodeCounter] += (E1[nodeCounter] + E2[nodeCounter] + E3[nodeCounter] + E4[nodeCounter])*SF
那么这将显著降低你的T带宽,并使你非常接近最大速度。
- C++ 多线程 - 与线程合并排序的算法替代
- 如何从多个线程并行安全地访问和写入复杂容器?
- OpenMP:共享同一算法的单线程和多线程实现
- 使用 vector<thread> 和 .join() 未并行运行的多线程C++程序
- C 多线程,在并行多个线程时获得SegFault
- 为什么在某些特定情况下具有多个线程(并行处理)会降低性能
- C++多线程算法创建在同一 CPU 线程上运行的多个线程
- MFC多线程程序可以以并行方法运行
- 多线程 - 彼得森算法不起作用
- 多线程galib247遗传算法陷入局部极大值
- C++STL多线程,并行运行计算
- 使用 c++ 的多线程和并行进程
- C++ STL 算法(列表排序)OpenMP/多线程实现
- 多线程 (openMP) - 多少个并行线程
- 为什么这种令人尴尬的并行算法的性能没有随着多线程而提高
- 多线程数独算法c++
- 没有多线程的c++套接字不同步/并行代码
- 面向通知-等待模式的c++多线程算法设计
- 高效实现多线程排序算法的关键是什么?幼稚的实现无法正常工作
- 从 Java 的多线程并行调用非线程安全的 DLL 函数