正确使用加载/存储
Posted
技术标签:
【中文标题】正确使用加载/存储【英文标题】:Use load/store correctly 【发布时间】:2015-07-01 15:27:46 【问题描述】:如何使用加载/存储来正确进行对齐的int16_t
字节交换?
void byte_swapping(uint16_t* dest, const uint16_t* src,
size_t count)
__m128i _s, _d;
for (uint16_t const * end(dest + count); dest != end; dest += 8, src += 8)
_s = _mm_load_si128((__m128i*)src);
_d = _mm_or_si128(_mm_slli_epi16(_s, 8), _mm_srli_epi16(_s, 8));
_mm_store_si128((__m128i*) dest, _d);
【问题讨论】:
您遇到了什么具体问题?如果只是缓冲区没有正确对齐,那么要么修复对齐,要么使用_mm_loadu_si128
/_mm_storeu_si128
。
我试过 _mm_loadu_si128/_mm_storeu_si128 ,它在 VS 2015 中也崩溃了。或者任何其他方式来编写这个 16 字节交换 uisng SSE 内在函数?
从您向我们展示的内容来看,该代码看起来不错 - 您可以发布 MCVE 吗?
那么从 VS 2015 break 开始,你认为问题是什么?
如果没有 MCVE,几乎不可能为您提供帮助。我看到的唯一明显错误是,如果 count
不是 8 的倍数,您的例程将失败 - 这似乎就是您的特定示例崩溃的原因,因为 172 不是 8 的倍数。
【参考方案1】:
当count
不是 8 的倍数,或者src
或dest
不是 16 字节对齐时,您的代码将失败。
这是您的代码的固定(和测试)版本:
void byte_swapping(uint16_t* dest, const uint16_t* src, size_t count)
size_t i;
for (i = 0; i + 8 <= count; i += 8)
__m128i s = _mm_loadu_si128((__m128i*)&src[i]);
__m128i d = _mm_or_si128(_mm_slli_epi16(s, 8), _mm_srli_epi16(s, 8));
_mm_storeu_si128((__m128i*)&dest[i], d);
for ( ; i < count; ++i) // handle residual elements
uint16_t w = src[i];
w = (w >> 8) | (w << 8);
dest[i] = w;
【讨论】:
谢谢保罗。让我今晚试试。实际上我们正在开发一个 xbox 360 模拟器,进展非常顺利。 github.com/benvanik/xenia 它接近并且看起来更好,但它以某种方式像这样被切断i.stack.imgur.com/pT9GP.jpg 好的 - 我怀疑错误存在于其他地方 - 您可以通过将byte_swapping
替换为简单的标量实现来证明这一点 - 我希望您会看到相同的结果。
好的 - 你能在你的问题中包含标量版本吗?
for (size_t i = 0; i > 8) & 0xff) | ((src[i]
以上是关于正确使用加载/存储的主要内容,如果未能解决你的问题,请参考以下文章
托管在通过 Azure Front Door 访问的存储帐户上的静态网站未正确加载
将文件从 Azure Blob 存储加载到 Azure SQL DB:错误代码 86 指定的网络密码不正确
正确使用 Classloader(尤其是在 Android 中)