linux – MOVDQU指令页边界

前端之家收集整理的这篇文章主要介绍了linux – MOVDQU指令页边界前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个简单的测试程序,加载一个xmm寄存器
movdqu指令通过页边界访问数据(OS = Linux).

如果以下页面被映射,这样做很好.如果不是
映射然后我得到一个SIGSEGV,这可能是预期的.

然而,这减少了非对齐负载的有用性
一点点.另外SSE4.2指令(如pcmpistri)哪个
允许未对齐的内存引用似乎表现出这种行为
以及.

没关系,除了很多strcmp的实现
使用pcmpistri,我发现似乎没有解决这个问题
在所有这一切 – 我已经能够设法琐碎的测试
导致这些实现失败,而字节在一个时间是微不足道的
strcmp实现将使用相同的数据布局正常工作.

还有一个注意事项 – 它出现在GNU C库实现中
64位Linux有一个__strcmp_sse42变体似乎使用
pcmpistri指令以更安全的方式.实施
这个strcmp是相当复杂的,但它似乎是仔细尝试
以避免页面边界问题.我不知道这是否是由于
我上面提到的问题,或者是否只是尝试的副作用
通过对齐数据获得更好的性能.

无论如何,我的主要问题是 – 在哪里可以找到更多
关于这个问题?我输入了“movdqu交叉页边界”和
我可以想到Google的每个变体,但还没有遇到
任何特别有用的如果有人可以指出我的更多信息
对此,将不胜感激.

解决方法

首先,尝试访问未映射地址的任何算法将导致SegFault.如果非AVX代码流使用4字节负载来访问页面的最后一个字节,并且发现没有映射的“下一页”的前3个字节,那么它也会导致SegFault.没有?我相信“问题”是AVX(1/2/3)寄存器比“典型的”要大得多,那些不安全(但是被忽略)的算法被简单地扩展到更大的寄存器.

对齐加载(MOVDQA)永远不会有这个问题,因为它们不会跨越自己的大小或更大的边界.未对齐的负载可以有这个问题(正如你所注意到的)和“经常”.原因是该指令被定义为加载目标寄存器的全部大小.您需要非常仔细地查看指令定义中的操作数类型.您感兴趣的数据量无关紧要,重要的是指令的定义.

然而…

AVX1(Sandybridge)添加了一个“movedq”或“movdq”的“masked move”功能,但不会(在架构上)访问未映射的页面,只要掩码未被启用,该访问的那部分将被丢弃在该页面中.这是为了解决这个问题.一般来说,向前移动,加载/存储的蒙版部分(见AVX512)似乎也不会导致对IA的访问冲突.

(关于PCMPxSTRx的行为是一个很大的障碍,也许你可以添加15个字节的填充到你的“string”对象?)

猜你在找的Linux相关文章