我bad_alloc
从下面用 gcc 编译的代码中得到了一个抛出(尝试 4.9.3、5.40 和 6.2)。gdb 告诉我它发生在 unordered_map 的 initalizer_list 的最后一行。如果我注释掉 mmx 指令_m_maskmovq
,则没有错误。同样,如果我注释掉 unordered_map 的初始化,这没有错误。只有在调用 mmx 指令并使用 initializer_list 初始化 unordered_map 时,我才能获得bad_alloc
. 如果我默认构造 unordered_map 并调用map.emplace(1,1)
也没有错误。我已经在具有 48 个内核(intel xeon)和 376 GB RAM 的 centos7 机器上以及在 Ubuntu WSL 下的戴尔笔记本电脑(intel core i7)上运行它,结果相同。这里发生了什么?MMX 指令是否破坏了堆?Valgrind 似乎没有发现任何有用的东西。
编译器命令和输出:
$g++ -g -std=c++11 main.cpp
$./a.out
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted
源代码(main.cpp):
#include <immintrin.h>
#include <unordered_map>
int main()
{
__m64 a_64 = _mm_set_pi8(0,0,0,0,0,0,0,0);
__m64 b_64 = _mm_set_pi8(0,0,0,0,0,0,0,0);
char dest[8] = {0};
_m_maskmovq(a_64, b_64, dest);
std::unordered_map<int, int> map{{ 1, 1}};
}
更新:
_mm_empty() 解决方法确实修复了此示例。当使用一个线程执行向量指令而另一个线程使用 unordered_map 的多线程代码时,这似乎不是一个可行的解决方案。另一个有趣的点是,如果我对-O3
bad_alloc 进行优化,它就会消失。祈祷我们在生产过程中从未遇到过这个错误(畏缩)。