繁体   English   中英

读/写部分分配的对齐内存

[英]Read / write partially allocated aligned memory

关于访问未分配的内存有很多问题,这显然是未定义的行为。 但是接下来的情况呢?

请考虑以下结构,该结构对齐到16个字节,但仅占8个字节:

struct alignas(16) A
{
    float data[2]; // the remaining 8 bytes are unallocated
};

现在,我们通过SSE对齐的加载/存储内在函数访问16个字节的数据:

__m128 test_load(const A &a)
{
    return _mm_load_ps(a.data);
}

void test_store(A &a, __m128 v)
{
    _mm_store_ps(a.data, v);
}

这也是未定义的行为,我应该改用填充吗?

无论如何,由于Intel内在函数不是标准C ++,是否正在访问部分分配但对齐的内存块(不大于对齐的大小)在标准C ++中的未定义行为?

我同时解决了固有情况和标准C ++情况。 我对他们两个都感兴趣。

另请参见在x86和x64的同一页中读取缓冲区的末尾是否安全? 该问题的阅读部分基本上是该问题的重复部分。

它是根据ISO C ++标准的UB,但我认为像这样的只读访问确实可以安全地(即编译为您期望的asm)在提供Intel内部函数(可以自由定义所需的任何额外行为)的实现上)。 在asm中绝对是安全的,但是风险是,如果优化C ++编译器将UB转换为错误编译的代码,则它们可以证明没有什么可读取的,则可能会引起问题。 关于链接的问题有一些讨论。


在对象之外书写总是不好的 不要这样做,即使您放回了之前阅读的相同垃圾,也是如此:非原子加载/存储对可能是一个问题,具体取决于遵循结构的数据。

唯一可行的方法是在数组中知道接下来会发生什么,并且有未使用的填充。 例如,使用16B写出由3B重叠的3个float结构的数组。 (没有用于过度对齐的alignas ,因此数组将它们打包在一起而不会填充)。


将3结构float s就大于2个好得多的例子floats

对于(2个浮子)本具体例中可以只使用MOVSD做64位零延伸负荷,和MOVSD或MOVLPS做一个的低半部分的64比特存储__m128

语言律师对此的回答是“问题无足轻重”。 _mm_load_ps未在标准中定义,并且使用的ASM指令也未在标准中定义。 C ++不处理此问题。

至于第二个问题-从C ++访问未分配的内存显然是未定义的行为。 没有任何对象放置在此内存中,因此您无法访问它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM