【问题标题】:Parallel matrix product平行矩阵积
【发布时间】:2023-04-05 12:40:02
【问题描述】:

为了以并行模式计算 2 个矩阵 A 和 B(nxm 维度)之间的乘积,我有以下限制:服务器向每个客户端发送来自矩阵 A 的一些行,以及来自矩阵 A 的一些行矩阵 B。这不能改变。此外,客户端可以在彼此之间交换信息,以便计算矩阵乘积,但它们不能要求服务器发送任何其他数据。

这应该尽可能以最有效的方式完成,这意味着通过最小化进程之间发送的消息数量 - 被认为是一项昂贵的操作 - 并尽可能并行地进行小型计算。

根据我的研究,实际上客户端之间交换的最大消息数是 n^2,以防每个进程将其行广播给所有其他进程。现在,问题是,如果我最小化发送的消息数量——这将在 log(n) 左右用于分发输入数据——但是计算只能由一个或多个进程完成,但无论如何,它不是不再并行完成,这是问题的主要思想。

有什么更有效的算法可以计算这个乘积?

(我正在使用 MPI,如果它有什么不同的话)。

【问题讨论】:

  • 每个客户是否都知道哪些其他客户收到了哪些行,或者他们也必须要求弄清楚这一点?
  • 是的,每个客户都可以通过计算自己找出来。
  • 您确定客户端接收的是矩阵 B 的行而不是列吗?如果确实如此,那问题就会复杂化一些。
  • 确实是问题所在,客户端从矩阵 B 接收行并且没有足够的信息来计算结果矩阵中的元素。从矩阵 A 接收到的行中仍有未使用的元素,这就是它们需要与其他客户端交换信息的原因。
  • 确定是并行化的好问题?对于n 节点,它将需要n*n 流量,同时每个节点将产生更少的有用信息。

标签: algorithm matrix parallel-processing mpi


【解决方案1】:

要逐个元素地计算矩阵乘积C = A x B,您只需计算C(i,j) = dot_product(A(i,:),B(:,j))。即C的(i,j)元素是A的i行和B的j列的点积。

如果您坚持发送 A 行和 B 行,那么您将很难编写一个性能超过简单串行程序的并行程序。相反,您应该做的是将 A 的行和 B 的列发送到处理器以计算 C 的元素。如果您被限制发送 A 的行和 B 的行,那么我建议您这样做,但是计算服务器上的产品。也就是说,忽略所有工作处理器,只按顺序执行计算。

另一种方法是在工作处理器上计算部分点积并累积部分结果。这将需要一些棘手的编程;这是可以做到的,但如果在您第一次尝试时,您可以编写一个优于(在执行速度上)简单串行程序的程序,我会感到非常惊讶。

(是的,还有其他方法可以分解矩阵-矩阵乘积以进行并行执行,但它们比上述更复杂。如果您想研究这些,那么Matrix Computations 是开始阅读的地方。)

您还需要认真考虑您提出的效率衡量标准——最有效的消息传递程序将是不传递任何消息的程序。如果消息传递的成本远远超过计算的成本,那么无消息传递的实现将是两种措施中最有效的。不过,一般来说,并行程序效率的衡量标准是加速比与处理器数量的比值:因此,在 8 个处理器上加速 8 倍是非常有效的(而且通常是不可能实现的)。

如上所述,您的问题不是明智的。问题设置者错误地指定了它,或者您错误地陈述(或误解)了正确的规范。

【讨论】:

    【解决方案2】:

    有些不对劲:如果两个矩阵都有n x m 维度,那么它们不能相乘(除非n = m)。在 A*B 的情况下,A 的列数必须与 B 的行数一样多。您确定服务器没有发送 B 的转置行吗?这相当于从 B 发送列,在这种情况下解决方案是微不足道的。

    假设所有这些都已签出,并且您的客户确实从 A 和 B 获得了行:可能最简单的解决方案是让每个客户将其矩阵 B 的行发送给客户 #0,后者重新组合原始矩阵 B,然后将其列发送回其他客户端。基本上,客户端 #0 将充当实际上知道如何有效分解数据的服务器。这将是 2*(n-1) 消息(不包括用于重新组合产品矩阵的消息),但考虑到您已经需要 n 消息在客户端之间分配 A 和 B 矩阵,没有明显的性能损失(它仍然是 @ 987654325@消息)。

    这里最大的瓶颈显然是矩阵 B 的初始收集和重新分配,它的规模非常大,所以如果你有相当小的矩阵和很多进程,你最好在服务器上连续计算产品。

    【讨论】:

    • 好的,矩阵有 nxm 和 mxn 维度,很抱歉省略了这些信息。如果您打算从 B 中提取元素以发送列,则该问题涉及巨大的矩阵,很难使用。但是,要求是数据(A 和 B 矩阵)以行块的形式发送 - 因为它们实际上保存在内存中。
    【解决方案3】:

    我不知道这是不是作业。但如果它不是家庭作业,那么你可能应该使用图书馆。一个想法是scalapack

    http://www.netlib.org/scalapack/scalapack_home.html

    Scalapack 是用 fortran 编写的,但您可以从 c++ 中调用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      相关资源
      最近更新 更多