如何调试 _mm_mul_ps 函数?

how to debug a _mm_mul_ps function?

我有这个代码:

inline __m128 process(const __m128 *buffer) {
    __m128 crashTest;
    for (int i = 0; i < mFactor; i++) {
        crashTest = _mm_mul_ps(buffer[i], _mm_set1_ps((float)(((int32_t)1) << 16)));
    }

    return crashTest;
}

当我用一些“缓冲区”调用它时,它使应用程序崩溃(即分段错误)。

如何调试?发现哪个值会导致崩溃? 尝试了 try catch,但没有捕获到分段错误。

无法“cout”这个值,因为我在一个繁重的“音频”过程中(例如 44100 x n 秒 cout,这会冻结 i/o)。

有什么建议吗?

_mm_mul_ps 不是函数。它看起来像一个,但它编译成 single instruction,具体取决于编译器设置 mulpsvmulps。输出在完整的输入范围内得到了很好的定义,即使使用 INF、NAN 或 denormals 等奇怪的值也能做正确的事情。

如果该函数崩溃,可能的原因是内存访问。最有可能越界访问 buffer 参数。另一个可能的原因是参数不是 16 字节对齐的,尽管只有在编译成 mulps SSE 指令而不是 vmulps AVX 指令时才会崩溃。在这两种情况下,再多的打印都无济于事:您只需将崩溃从 _mm_mul_ps 移至矢量打印功能即可。

如果由于某种原因您不能使用调试器,#include <assert.h>并在那里进行一些检查。

检查范围不可靠且依赖于平台,但您仍然可以在 Windows 上使用 VirtualQuery API,并从 /proc/self/maps 文本中解析所有这些数字Linux.

上的文件

虽然检查对齐很简单,assert( 0 == ( ((size_t)buffer) % 16 ) );

P.S。然而,最好的长期解决方案是添加缓冲区大小参数。或者为输入缓冲区的末尾提供另一个指针。或者用 const std::vector<__m128>& 替换原始指针。使用所有这些方法,您将能够检测越界访问并优雅地抛出异常,而不是因访问冲突而导致进程崩溃。