在AVX-512加载和存储中使用掩码寄存器时,是否由于无效访问被掩码元素而引发故障?

时间:2019-02-02 20:18:16

标签: x86 avx avx512

当我进行写屏蔽的AVX-512存储时,如下所示:

vmovdqu8 [rsi] {k1}, zmm0

将所述指令的错,如果在{1} {}未映射的访问的存储器,但写掩码的一些部分是所有那些位置零(即,数据不是实际是由于改性面具)。

要求它的另一种方式是,如果这些AVX-512掩蔽存储有一个类似的故障抑制能力为[rsi, rsi + 63]在AVX引入。

1 个答案:

答案 0 :(得分:9)

如果被掩盖的元素接触无效内存,则不会引发任何故障。

enter image description here


这里有一些Windows测试代码来证明屏蔽确实可以抑制内存错误。

#include <immintrin.h>
#include <iostream>
#include <Windows.h>
using namespace std; 


int main(){
    const size_t PAGE = 4096;

    //  Map 2 pages.
    char* ptr = (char*)VirtualAlloc(
        nullptr, 2*PAGE,
        MEM_COMMIT,
        PAGE_READWRITE
    );

    //  Store 64 bytes across page boundary.
    cout << "Store across page boundary." << endl;
    _mm512_storeu_si512(ptr + PAGE - 32, _mm512_set1_epi8(-1));

    //  Unmap top page.
    cout << "Unmap top page." << endl;
    VirtualFree(ptr + PAGE, PAGE, MEM_DECOMMIT);

    //  Write on boundary masking out the part that touches the top (unmapped page).
    //  Does not crash because bad accesses are masked out.
    cout << "Store across page boundary, but mask out bytes that are on unmapped page." << endl;
    _mm512_mask_storeu_epi8(ptr + PAGE - 32, 0x00000000ffffffff, _mm512_set1_epi8(-1));

    //  Store 64 bytes across page boundary.
    //  Crashes because of bad access.
    cout << "Store across page boundary." << endl;
    _mm512_storeu_si512(ptr + PAGE - 32, _mm512_set1_epi8(-1));

    cout << "Release bottom page." << endl;
    VirtualFree(ptr, 0, MEM_RELEASE);

    system("pause");
}

输出:

Store across page boundary.
Unmap top page.
Store across page boundary, but mask out bytes that are on unmapped page.
Store across page boundary.
**Access violation**

此测试的工作方式如下:

  1. 映射2个相邻页面。
  2. 在页面边界上进行AVX512存储以证明两个页面都已映射。
  3. 取消映射上部页面。
  4. 执行相同的AVX512存储,但屏蔽掉上部页面上的字节。它不会崩溃。
  5. 重复第一个AVX512存储(无遮罩)。它崩溃了,从而证明了上层页面没有被映射,并且屏蔽屏蔽了崩溃。