我正在尝试实现一个高性能的 C++ 程序,每个周期我将 8 个字节加载到 MMX 寄存器然后处理它们,但是当我到达字符串的末尾时我当然想停止。
所以这是我找到的解决方案,每个循环加载8个字节,将每个字节与\0进行比较,如果有\0则采取预防措施。问题是,如果我的数据是 4 个字节,并且在第一个周期中加载 8 个字节,那么我从另一个应用程序内存空间加载 4 个字节。
这会给我带来麻烦吗?或者只是“噪音”来自这些字节,这对我来说是完全可以接受的,因为我一了解 \0 字符就会处理它。
SSE2 自 2001 年以来一直存在,现在基本上得到了普遍支持,但也许您有充分的理由坚持使用 MMX(可能针对嵌入式 P3?)
无论如何,问题在 SSE2 中仍然存在,是的,进行可以扩展到已知有效内存区域之外的任意加载是不好的。C++ 坚持认为超出它的任何负载都是不好的,但实际上它可以产生任何影响的唯一方法是如果您触摸下一页并且它是无效的。
使用对齐加载(MMX 不区分对齐加载和未对齐加载,但您当然仍然可以对齐地址)确保如果您正在加载的第一个字节在有效页面上,那么最后一个字节也是。因此,如果您首先逐字节处理,直到您位于对齐的地址,然后继续对齐加载,您会没事的。
如果您正在使用 SIMD 指令来获得更高的性能,那么使用您自己的内存分配也是合理的。在您的情况下,您需要分配的内存块是所用 SIMD 指令宽度的倍数:MMX 为 8,SSE 为 16,AVX 为 32。为此,最好使用标准函数 _mm_malloc 和 _mm_free(对于 Visual Studio)或 posix_memalign(对于 GCC)。