【发布时间】:2011-09-19 12:31:48
【问题描述】:
我正在编写一个使用 pthreads 对二维矩阵进行波前模式计算的 C 程序。为了获得良好的性能,我以交错的方式将几行分配给每个线程,如下所示:
线程 0 ------------------
线程 1 ------------------
线程 2 ------------------
线程 3 ------------------
线程 0 ------------------
线程 1 ------------------
线程 2 ------------------
线程 3 ------------------
等等
在这个计算中,我认为这是唯一可行的拆分,因为每个线程都需要在每一行上计算的新值,并且在它们可用之前不能进一步移动。 现在,这里的问题是线程 1 需要线程 0 在其行上计算的值,因此它必须落后于线程 0 而不是走在它前面。为此,我将每一行分成块,并用临界区保护每个块。计算如下:
线程 0 -----------
线程 1 ------
线程 2 ---
这样总是第 i 行必须落后于第 i - 1 行。我希望你理解这个想法。 我已经实现了这个想法,我正在一台双四核系统的机器上对其进行测试。我正在经历奇怪的行为。结果计算正确,但运行时间在比连续时间少 8 倍到多于连续时间之间变化。实际上,12000 x 12000 矩阵的连续运行时间为 16 秒,并行运行时间介于 2 到 17 秒之间,并且在两次连续运行时通常会有所不同。
我最初的想法是这个问题对局部性非常敏感,所以如果假设线程 0 和线程 1 被安排在不同的物理处理器上,我当然可能会得到糟糕的性能。在 /proc/cpuinfo 中环顾四周,我推断内核的映射使得 0、2、4、6 位于处理器 0 上,而 1、3、5、7 位于处理器 1 上。 然后,在创建线程时,我使用 pthread_setaffinity_np 为正确核心上的线程设置亲和性。然而,什么都没有改变。我也尝试过使用 pthread_attr_setaffinity_np 和 sched_setaffinity 但我得到了相同的随机运行时间。
要么内核忽略了我的关联调用,要么这不是问题所在。 我真的希望有人可以帮助我,因为我已经没有想法了。谢谢。
【问题讨论】:
-
正在将问题简化为标准矩阵和向量运算,并使用现成的并行线性代数库,例如来自 INTEL 或 AMD 的选项?
-
恐怕不行,因为应用程序即将完成,并且分配需要使用基本线程。此外,我认为出于教学原因调查此问题的原因是值得的。 :)
标签: c multithreading pthreads parallel-processing