并行化GPU

时间:2017-09-27 23:35:43

标签: matlab parallel-processing gpu sequential

我有一个for循环,其中向量的当前索引取决于我试图在MATLAB中为GPU并行化的先前索引。

  1. A是nx1已知载体
  2. B是nx1输出向量,初始化为零。
  3. 代码如下:

    for n = 1:size(A)
        B(n+1) = B(n) + A(n)*B(n) + A(n)^k + B(n)^2
    end
    

    我查看了this类似的问题并尝试为recurrence relation找到一个简单的封闭表单,但找不到。

    我可以在 A(n)^ k 术语的第一个链接中提到前缀和,但我希望有另一种方法来加速循环。

    感谢任何建议!

    P.S。我的真实代码涉及沿2D切片索引和求和的3D数组,但是对于1D情况的任何帮助都应该转换为3D缩放。

1 个答案:

答案 0 :(得分:1)

一个词"并行化"神奇地说,但调度规则适用:

您的问题不在于努力尝试将纯 SEQ 流程转换为 PAR -re - 代表,但在处理这样做的成本时,如果你确实坚持不惜任何代价去 PAR

m = size(A);                                                                  %{

             +---+---+---+---+---+---+---+---+---+---+---+---+---+ .. +---+
const A[] := | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D |    | M |
             +---+---+---+---+---+---+---+---+---+---+---+---+---+ .. +---+
                           :
                            \
                             \
                              \
                               \
                                \
                                 \
                                  \
                                   \
                                    \
                                     \
                                      \
             +---+---+---+---+---+ ..  +  .. +---+---+---+---+---+ .. +---+
  var B[] := | 0 | 0 | 0 | 0 | 0 |     :     | 0 | 0 | 0 | 0 | 0 |    | 0 |
             +---+---+---+---+---+ ..  :  .. +---+---+---+---+---+ .. +---+   }%
                    %%     :   ^       : 
                    %%     :   |       :
      for   n = 1:m %%     :   |       : 
          B(n+1) =( %% ====:===+       :                       .STO NEXT n+1
                    %%     :           : 
                    %%     v           :                    
                         B(n)^2  %%    :        { FMA B, B,    .GET LAST n ( in SEQ :: OK, local data, ALWAYS )
                  +      B(n)    %%    v                 B  }              ( in PAR :: non-local data. CSP + bcast + many distributed-caches invalidates )
                  +      B(n) *     A(n)    %%  { FMA B, A,
                  +                 A(n)^k  %%           ApK}
                    );
      end

SEQ - 流程数据依赖关系重复出现(需要重新使用 最后 B(n-1) < / strong>对于 NEXT B(n) 的分配,任何尝试进行此类SEQ计算的工作都在< strong> PAR 必须引入已知值的系统范围的通信,然后才能在相应的&#34;之前的#34;之后计算新的&#34; - 值。 B(n-1)已经过评估和分配 - 通过纯序列SEQ循环评估链,因此不是在所有前一个单元格连续处理之前 - LAST NEXT 步骤始终需要 一块,参考 &#34;十字路口&#34; for()中 - 循环迭代器依赖关系图(有了这个,所有其余的都必须在&#34;队列&#34;中等待,才能成为他们的两个原始.FMA - s + .STO导致下一个混合货币被灌输& #34;队列&#34; )。

是的,可以强制执行&#34;成为PAR执行的公式,但这些 最后 值的成本正在传达&#34;跨越&#34; PAR - 执行结构(朝向 NEXT )通常非常昂贵(在资源和累积延迟方面 - 要么损坏SIMT优化的调度程序延迟 - 屏蔽或阻止所有线程,直到接收到他们所依赖的&#34;邻居&#34; - 分配 最后 值 - 并且如果不先获取它就无法继续 - - 其中任何一项都有效地破坏了投入PAR 所投入的所有努力的潜在好处。

即使只是一对FMA - s也不足以证明所有PAR工作的附加费用 - 实际上是一项极少量的工作。“ p>

除非一些非常数学和密集的&#34;处理正在进行中,所有额外成本都不容易调整,这种尝试引入PAR - 计算模式只会产生负面(不利)影响,而不是任何希望的加速。在所有专业案例中,应该在概念验证阶段( PoC )表达所有附加成本,然后才决定是否可以采用任何可行的PAR方法,以及如何实现&gt;&gt;的加速1.0 x

依靠广告理论上的GFLOPS和TFLOPS是一个废话。您的实际GPU内核永远无法重复所宣传的测试&#39;性能数据(除非你运行完全相同的优化布局和代码,哪一个不需要,做一个?)。人们通常需要计算自己特定的算法,这与一个问题域有关,不愿意人为地对齐所有玩具问题元素,以便GPU-silicon不必等待真实数据并且可以享受一些基于缓存/寄存器的ILP工件,在大多数现实问题解决方案中几乎无法实现。 如果有一个建议步骤 - 请始终首先评估开销公平的PoC,看看,如果有任何加速的机会,在潜入任何资源并投入时间和金钱进行原型设计详细设计之前。测试

经常性和弱处理GPU内核有效负载几乎在每种情况下都会努力争取至少获得额外的开销时间(与双向数据传输相关(H2D + D2H)+内核代码相关的负载)。