如何调试 _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,具体取决于编译器设置 mulps
或 vmulps
。输出在完整的输入范围内得到了很好的定义,即使使用 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>&
替换原始指针。使用所有这些方法,您将能够检测越界访问并优雅地抛出异常,而不是因访问冲突而导致进程崩溃。
我有这个代码:
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,具体取决于编译器设置 mulps
或 vmulps
。输出在完整的输入范围内得到了很好的定义,即使使用 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>&
替换原始指针。使用所有这些方法,您将能够检测越界访问并优雅地抛出异常,而不是因访问冲突而导致进程崩溃。