gpt4 book ai didi

matrix - `matrix * vector`、 `matrix’ * vector` 和 `copy(matrix’ ) * vector` 之间的非直观性能差异

转载 作者:行者123 更新时间:2023-12-05 00:10:26 27 4
gpt4 key购买 nike

问题来自 Julia Discourse

我正在使用 Julia 1.2。这是我的测试:

a = rand(1000, 1000)
b = adjoint(a)
c = copy(b)

@btime a * x setup=(x=rand(1000)) # 114.757 μs
@btime b * x setup=(x=rand(1000)) # 94.179 μs
@btime c * x setup=(x=rand(1000)) # 110.325 μs

我在期待 c 至少不会变慢。

检查后 stdlib/LinearAlgebra/src/matmul.jl ,事实证明 Julia 通过了 b.parent (即 a )到 BLAS.gemv ,不是 b ,而是切换 LAPACK 的 dgemv_ 进入一种不同且明显更快的模式。

我是否正确假设加速来自这样一个事实,即内存以更有利的方式对齐 dgemv_ 确实,当它在 中时反式 = T 模式?如果是这样,那么我猜这不是可行的,除了可能以某种方式在文档中提及问题。如果我的假设是错误的,有什么可以做的吗?

最佳答案

@stevengj 在同一个 Discourse 帖子中的回答:

Am I correct in assuming that the speedup comes from the fact that the memory is aligned in a more favorable way for whatever dgemv_ does, when it’s in a trans = T mode?



关闭。它确实与内存有关,但它是关于 locality ,不对齐。要理解的基本事情是,由于 cache lines 的存在,从内存中访问连续(或至少附近)数据比从内存中访问数据更有效。 . (连续访问在使用 SIMD 指令方面也有一些优势。)

Julia 将矩阵存储在 column-major order 中,以便列在内存中是连续的。因此,当您将转置矩阵(尚未复制的)乘以向量时,它可以将其计算为连续列(= 转置行)与连续向量的点积,其具有良好的 空间局部性因此可以有效地利用缓存行。

相比之下,要将非转置矩阵乘以向量,您将矩阵的非连续行的点积与向量相乘,并且更难有效利用缓存行。在这种情况下,为了改善空间局部性,像 OpenBLAS 这样的优化 BLAS 实际上一次计算多行(一个“块”)与向量的点积,我相信——这就是为什么它只慢了 10% 而不是更糟。 (事实上​​,即使是转置的情况也可能会做一些阻塞以将向量保持在缓存中。)

关于matrix - `matrix * vector`、 `matrix’ * vector` 和 `copy(matrix’ ) * vector` 之间的非直观性能差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58126704/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com