在openmp中使用不同线程组装矢量时缩放不良

Posted

技术标签:

【中文标题】在openmp中使用不同线程组装矢量时缩放不良【英文标题】:poor scaling when assembling vector using different threads in openmp 【发布时间】:2015-10-12 00:16:09 【问题描述】:

我正在尝试使用多个线程组装一个大向量。每个线程都在读取自己的线程向量并写入大向量的特定部分(索引是连续的)。

条目的总数是一个固定的数字N,每个线程将N/numberOfThreads个条目写入大向量。我做了以下实验:

//each vector contains the data that a particular thread needs to process
//and has the same length = N/numberOfThreads;
vector<vector<double> > threadVectors; 
//the big vector that each thread needs to write into
vector<double> totalVector(N); 

//initialize threadVectors ...

#pramga omp parallel

    int threadId = omp_get_thread_num();
    vector<double>& threadVector = threadVectors[threadId];
    int globalStartId = threadId * threadVector.size();
    std::copy(threadVector.begin(), threadVector.end(),
        totalVector.begin() + globalStartId);

我正在对并行部分进行 10 次重复和 N = 1e7 的计时。在我尝试了 1-24 线程后,我得到了以下加速:

线程数,时间,加速w.r.t到单线程

1 : 0.1797 加速 0.99

2 : 0.1362 加速 1.31

3 : 0.1430 加速 1.25

4 : 0.1249 加速 1.43

5 : 0.1314 加速 1.36

6 : 0.1446 加速 1.23

7 : 0.1343 加速 1.33

8 : 0.1414 加速 1.26

9 : 0.1370 加速 1.30

10 : 0.1387 加速 1.28

11 : 0.1434 加速 1.24

12 : 0.1344 加速 1.33

13 : 0.1299 加速 1.37

14 : 0.1303 加速 1.37

16 : 0.1362 加速 1.31

18 : 0.1341 加速 1.33

20 : 0.1384 加速 1.29

22 : 0.1319 加速 1.35

23 : 0.1303 加速 1.37

24 : 0.1298 加速 1.37

这台机器是 12 核超线程(24 线程)。看起来加速很差,算法不涉及任何比赛或锁定。

有人知道这个问题吗?

【问题讨论】:

您尝试了发布和调试版本? 我用 g++ -fopenmp -O3 编译 你的处理器到底是为什么?你确定你没有一个每个有六个内核的两个插槽系统吗?可能不是因为那样您的缩放比例至少会增加两倍。 ***.com/questions/11576670/… 请注意,您使用的是#pragma omp parallel,它实际上是并行执行代码。但是,在您的情况下,每个线程实际上都在计算相同的值,并且您没有在它们之间分配工作。例如,您需要一个#pragma omp 并行。 【参考方案1】:

因为您的线程任务是非常内存密集型,将数据从一个内存块复制到另一个内存块,性能受内存限制。这不是很好扩展的东西。添加更多内核无济于事,因为它们都在等待来自主内存的数据。这就是为什么你的结果在两个线程中得到了轻微的改进,但之后没有额外的改进。

让它运行得更快的唯一方法是加快你的内存,但这是一个硬件问题。

【讨论】:

更具体地说是公交车。无论如何,公共汽车一次不允许超过一个访问。您要么将其保存在 CPU 上的缓存中,要么付出代价。

以上是关于在openmp中使用不同线程组装矢量时缩放不良的主要内容,如果未能解决你的问题,请参考以下文章

Openmp 多线程代码在使用多个线程时给出不同的答案

使用 openmp 时运行的线程数不一致

尝试在其线程函数参数中将不同的值传递给 openMp 线程

在不同的线程下运行相同的代码有啥意义 - openMP?

确保混合 MPI / OpenMP 在不同的内核上运行每个 OpenMP 线程

在 Openmp (C++) 中销毁线程