【问题标题】:implementing matrix vector multiplication in assembly在汇编中实现矩阵向量乘法
【发布时间】:2011-08-22 08:37:12
【问题描述】:

我有一个算法可以一遍又一遍地执行线性代数的树步骤,

loop{
  first I multiply a Vector and a Matrix, 
  Second I calculate the sum of elements in the Vector 
  and Thirdly I scale the vector using the sum, making sure the vectors elements scale to one.
}

我正在使用 BLAS 进行操作,这有点快,但它需要对数据进行树运行,每一步一个。现在我想知道将这些步骤合并为一个是否会有所收获,只需要运行一次数据。

是否有人对如何以最佳方式实现这些调用有任何经验,我的矩阵约为 100*100,向量有 100 个元素。

我认为该向量可以放入 8 个 128 字节 mmx 寄存器中。让乘法非常快,有什么想法吗?

【问题讨论】:

  • 通常编译器应该为此类算法生成好的代码。你检查过 C 编译器生成的程序集吗?
  • 嗨@m0skit0,是的,有人会认为编译器会擅长这种事情,因为它只是一种扫描算法,但我做了一个“手动”实现。首先,我将其与 Intel mkl 提供的实现进行了比较,而 Intel 和其他 BLAS impl 的表现还算不错。我认为在汇编中实现这一点是要走的路,也许从矢量-矢量 mult impl 开始。并从那里开始工作。
  • 您使用了哪个编译器以及哪些优化开关处于活动状态?你试过 GCC 吗?
  • @m0skit0 没关系,编译器通常不擅长矢量化代码。

标签: c optimization assembly blas


【解决方案1】:

优化的 BLAS 库是非常棘手的代码,除非您是 asm 编程专家并了解 CPU 的缓存性能,并且愿意花费大量时间测试各种方法,否则您不太可能做得更好.如果你想看看它是如何完成的,你可以下载并查看 GOTO BLAS 的源代码(用 asm 实现,是的)。

我不确定如何对您的代码进行任何实质性优化。我怀疑已经在 N=100 时,矩阵向量乘积的 O(N^2) 将主导运行时间,并且算法中的第二步和第三步相当微不足道。所以尝试结合所有 3 个步骤看起来并没有那么有用。

我想你可以做的一件小事,除非你已经在做,否则在第三步中乘以总和的倒数,而不是除以总和;除法比乘法昂贵得多。例如

double my_sum = sum(my_vector); double tmp = 1 / my_sum; for (i=...) { my_vector[i] *= tmp; }

【讨论】:

  • 我猜他是对的,如果他假设他可以在结合 3 个任务时进行优化。您可以在进行矩阵乘法时进行总结。这有两个优点:首先,您可以节省额外的循环和开销(即增加循环变量),其次:您已经将向量元素加载到缓存中以进行矩阵向量乘法,并且可以重用它们进行求和(顺便说一句:如果您想要删除求和步骤,您还可以添加一个额外的矩阵行,它只包含 1)。但你是对的:N^2 将占主导地位,与它相比增益非常小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 2020-03-16
  • 2020-01-17
  • 2016-01-23
相关资源
最近更新 更多