【发布时间】:2021-08-28 16:52:16
【问题描述】:
我正在尝试执行一个简单的操作。我有一个大小为 A x B 的矩阵。我有一个长度为 C 的索引列表,我想通过根据索引从第一个矩阵中收集行来制作一个 C x B 矩阵。即索引 i 告诉我将第一个矩阵中的哪一行放入第二个矩阵的第 i 行。
我对索引进行了预排序,因此算法输入是固定的:我从 A x B 矩阵加载行并将该行写入 C x B 矩阵中的所有行。
代码如下所示:
for(int i = 0;i < A; i ++)
{
for(int k = offsets[i]; k < offsets[i+1]; k ++)
{
int dest = index1[k];
for(int j = 0;j < C/ 8; j++)
{
__m256 a = _mm256_load_ps(&input[i * C + j * 8]);
_mm256_store_ps(&output[dest * C + j * 8] ,a);
}
}
}
代码完全被写入内存所限制。 当 C 较小时,此代码是有效的。然而,当 C 增加时,它的扩展性很差,我推测这是由于缓存行为。 (与 C = 256 相比,C = 1024 需要 10 倍的时间)。
我尝试在 C 维度进行阻塞:
for(int c = 0; c < C; c+= K){
for(int i = 0;i < A; i ++)
{
for(int k = offsets[i]; k < offsets[i+1]; k ++)
{
int dest = index1[k];
for(int j = 0;j < C/ 8 / K; j++)
{
__m256 a = _mm256_load_ps(&input[i * C + c + j * 8]);
_mm256_store_ps(&output[dest * C + c + j * 8] ,a);
}
}
}
}
这实际上会进一步减慢代码速度。
有什么建议吗?
【问题讨论】:
-
如果您只触及每个值一次,阻塞无法帮助您解决内存瓶颈问题。它可以提供帮助,例如如果您使用更昂贵的操作(例如矩阵-矩阵乘积)进行提取。
-
我不明白为什么当C维度增加时内存瓶颈会加剧。不幸的是,我没有任何东西可以用于内存写入。
-
请注意,在许多机器上,内存通常不会因为只有一个核心而饱和(这里有点平行 mat vélo(除了后面说的流存储)
-
流媒体商店你指的是vmovntps吗?
标签: c performance caching linear-algebra avx2