【发布时间】:2020-01-29 08:03:03
【问题描述】:
我试图使用 AVX512 内在函数来矢量化我的矩阵乘法循环(平铺)。我使用 __mm256d 作为变量来存储中间结果并将它们存储在我的结果中。但是,不知何故,这会触发内存损坏。我不知道为什么会这样,因为非 AVX 版本可以正常工作。此外,另一个奇怪的事情是,瓷砖大小现在会以某种方式影响结果。
矩阵结构附在以下代码部分中。该函数采用两个矩阵指针 m1 和 m2 以及一个整数作为 tileSize。感谢@harold 的反馈,我现在已将矩阵 m1 的 _mm256_load_pd 替换为广播。但是,内存损坏问题仍然存在。我还在下面附上了内存损坏的输出
__m256d rResult rm1, rm2, rmult;
for (int bi = 0; bi < result->row; bi += tileSize) {
for (int bj = 0; bj < result->col; bj += tileSize) {
for (int bk = 0; bk < m1->col; bk += tileSize) {
for (int i = 0; i < tileSize; i++ ) {
for (int j = 0; j < tileSize; j+=4) {
rResult = _mm256_setzero_pd();
for (int k = 0; k < tileSize; k++) {
// result->val[bi+i][bj+j] += m1.val[bi+i][bk+k]*m2.val[bk+k][bj+j];
rm1 = _mm256_broadcast_pd((__m128d const *) &m1->val[bi+i][bk+k]);
rm2 = _mm256_load_pd(&m2->val[bk+k][bj+j]);
rmult = _mm256_mul_pd(rm1,rm2);
rResult = _mm256_add_pd(rResult,rmult);
_mm256_store_pd(&result->val[bi+i][bj+j],rResult);
}
}
}
}
}
}
return result;
*** Error in `./matrix': free(): invalid next size (fast): 0x0000000001880910 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x81609)[0x2b04a26d0609]
./matrix[0x4016cc]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x2b04a2671495]
./matrix[0x400e29]
======= Memory map: ========
00400000-0040c000 r-xp 00000000 00:2c 6981358608 /home/matrix
0060b000-0060c000 r--p 0000b000 00:2c 6981358608 /home/matrix
0060c000-0060d000 rw-p 0000c000 00:2c 6981358608 /home/matrix
01880000-018a1000 rw-p 00000000 00:00 0 [heap]
2b04a1f13000-2b04a1f35000 r-xp 00000000 00:16 12900 /usr/lib64/ld-2.17.so
2b04a1f35000-2b04a1f3a000 rw-p 00000000 00:00 0
2b04a1f4e000-2b04a1f52000 rw-p 00000000 00:00 0
2b04a2134000-2b04a2135000 r--p 00021000 00:16 12900 /usr/lib64/ld-2.17.so
2b04a2135000-2b04a2136000 rw-p 00022000 00:16 12900 /usr/lib64/ld-2.17.so
2b04a2136000-2b04a2137000 rw-p 00000000 00:00 0
2b04a2137000-2b04a2238000 r-xp 00000000 00:16 13188 /usr/lib64/libm-2.17.so
2b04a2238000-2b04a2437000 ---p 00101000 00:16 13188 /usr/lib64/libm-2.17.so
2b04a2437000-2b04a2438000 r--p 00100000 00:16 13188 /usr/lib64/libm-2.17.so
2b04a2438000-2b04a2439000 rw-p 00101000 00:16 13188 /usr/lib64/libm-2.17.so
2b04a2439000-2b04a244e000 r-xp 00000000 00:16 12867 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
2b04a244e000-2b04a264d000 ---p 00015000 00:16 12867 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
2b04a264d000-2b04a264e000 r--p 00014000 00:16 12867 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
2b04a264e000-2b04a264f000 rw-p 00015000 00:16 12867 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
2b04a264f000-2b04a2811000 r-xp 00000000 00:16 13172 /usr/lib64/libc-2.17.so
2b04a2811000-2b04a2a11000 ---p 001c2000 00:16 13172 /usr/lib64/libc-2.17.so
2b04a2a11000-2b04a2a15000 r--p 001c2000 00:16 13172 /usr/lib64/libc-2.17.so
2b04a2a15000-2b04a2a17000 rw-p 001c6000 00:16 13172 /usr/lib64/libc-2.17.so
2b04a2a17000-2b04a2a1c000 rw-p 00000000 00:00 0
2b04a2a1c000-2b04a2a1e000 r-xp 00000000 00:16 13184 /usr/lib64/libdl-2.17.so
2b04a2a1e000-2b04a2c1e000 ---p 00002000 00:16 13184 /usr/lib64/libdl-2.17.so
2b04a2c1e000-2b04a2c1f000 r--p 00002000 00:16 13184 /usr/lib64/libdl-2.17.so
2b04a2c1f000-2b04a2c20000 rw-p 00003000 00:16 13184 /usr/lib64/libdl-2.17.so
2b04a4000000-2b04a4021000 rw-p 00000000 00:00 0
2b04a4021000-2b04a8000000 ---p 00000000 00:00 0
7ffc8448e000-7ffc844b1000 rw-p 00000000 00:00 0 [stack]
7ffc845ed000-7ffc845ef000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
【问题讨论】:
-
除了不提供minimal reproducible example之外,您正在计算的内容只是与矩阵乘积模糊相关(例如,您从未将
rResult重置为零,但您多次覆盖result->val[bi+i][bj+j]) -- 我建议首先实现一个标量变量进行比较。您的“内存损坏”的原因可能是您的内存未对齐。试试_mm256_loadu_pd和_mm256_storeu_pd(或者更好,确保你的记忆是对齐的)。 -
为什么要广播
doubles 的对,而不是_mm256_broadcast_sd或_mm256_set1_pd()?没有多大意义。还有,你看我的回答了吗?我仍然认为它可能解释了内存损坏,除非您的矩阵大小是瓦片宽度的倍数。 Harold 的回答只是谈论数学正确性问题,与数组边界问题分开。 -
您发布的代码不包含对
free()的任何调用,也就是说,您的(当前)内存损坏的原因在其他地方。提供minimal reproducible example!阅读该链接以了解如何以及为什么! -
@chtz 事实上,没有一个免费的功能。我猜内存损坏是指针在某处溢出。
-
您是否故意无视我的 MRE 请求?您是否知道 C++ 可能会调用
free(),例如通过delete运算符或容器的析构函数?
标签: c++ matrix optimization intrinsics avx