我正在编写一个 C 程序,使用 pthreads 在二维矩阵上进行波前模式计算。为了获得良好的性能,我以交错的方式将几行分配给每个线程,如下所示:
线程0 ------------------
线程 1 ------------------
线程 2 ------------------
线程 3 ------------------
线程0 ------------------
线程 1 ------------------
线程 2 ------------------
线程 3 ------------------
etc.
在这个计算中,我认为这是唯一可行的分割,因为每个线程都需要在每行上计算的新值,并且在它们可用之前无法进一步移动。
现在,这里的问题是线程 1 需要线程 0 在其行上计算的值,因此它必须落后于线程 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 但我得到相同的随机运行时间。
要么内核忽略了我的关联调用,要么这不是问题。
我真的希望有人可以帮助我,因为我已经没有想法了。谢谢。
内核不会忽略您的亲和力调用,这不是问题所在。
看起来像是缓存未命中。如果您的线程没有通过相同的数据互连,您可以在行之间留出很大的内存间隙以避免这种情况。
尝试制作单行数据大小的块(64字节)
尝试让线程 0 读取 64 个字节,只有在此之后线程 1 才会从同一位置读取数据 - 依此类推。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)