在矩阵乘法 C++ SIMD 编程中检测到 Stack Smashing

Stack Smashing Detected in Matrix Multiplication C++ SIMD Programming

我刚刚使用 C++ 学习了 simd 编程,我可以轻松地执行加法和减法,但我发现矩阵乘法有问题。

当我编译它时使用: gcc -o auto-vector auto-vector.cpp -lstdc++

它已编译,但是当我尝试 运行 它时,它说: 经过时间:3e-06 秒 * 检测到堆栈粉碎 *:已终止

它说检测到堆栈粉碎但它也测量经过的时间。

我的代码编译了吗?

//gcc -o auto-vector auto-vector.cpp -lstdc++
#include "xmmintrin.h"
#include <chrono> // for high_resolution_clock
#include <iostream>

int main()
{
  float A[4][4] = {{16, 2, 77, 40}, {16, 2, 77, 40}, {16, 2, 77, 40}, {16, 2, 77, 40}};
  float B[4][4] = {{16, 2, 77, 40}, {16, 2, 77, 40}, {16, 2, 77, 40}, {16, 2, 77, 40}};
  float C[4][4] = {};

  __m128 a_vec, b_vec, c_vec;
  int N = 4;

  // Record start time
  auto start = std::chrono::high_resolution_clock::now();

  for (int i = 0; i < N; i++)
  {
    for (int j = 0; j < N; j++)
    {
      c_vec = _mm_set1_ps(0);

      for (int k = 0; k < N; k++)
      {
        a_vec = _mm_set1_ps(A[i][k]);
        b_vec = _mm_loadu_ps(&B[k][j]);

        c_vec = _mm_add_ps(_mm_mul_ps(a_vec, b_vec), c_vec);
      }

      _mm_storeu_ps(&C[i][j], c_vec);
    }
  }

  // Record end time
  auto finish = std::chrono::high_resolution_clock::now();

  std::chrono::duration<double> elapsed = finish - start;

  std::cout << "Elapsed time: " << elapsed.count() << " s\n";

  return 0;
}

这意味着你存储了一个堆栈数组的末尾,你很幸运它在你的堆栈帧的顶部所以 -fstack-protector-strong 可以为你捕获错误而不是仅仅踩到其他本地人.

例如C[3][3] 的 16 字节存储触及 C[3][3 .. 7].

您正在对 j 进行自动矢量化,但您忘记将 j 递增 4 而不是 1,并使用 j < N - 3 作为循环边界.


此外,如果您想要有意义的计时结果,请确保使用 gcc -O3 进行编译。或者最好是 gcc -O3 -march=native -ffast-math -flto-fprofile-generate / -fprofile-use.

此外,您正在测试 手动 矢量化,但您的评论说 "auto-vector".


编码风格:在您第一次使用时声明您的 __m128 变量。喜欢
__m128 c_vec = _mm_setzero_ps();