在我的程序中,我想分配32 byte
对齐的内存以使用SSE / AVX。我想分配的金额大约是2000*1300*17*17*4(large data set)
。我尝试使用函数_aligned_malloc()
和_mm_malloc
但是对于更大的大小,它不会分配内存并导致访问冲突异常。如果分配的金额很小,大约512*320*4*17*17(small data set)
,那么代码工作正常。
这里,当为大数据集分配时,这些函数返回空指针。但是当输入数据大小很小时,它可以正常工作。此外,如果我只使用new
使用未对齐的内存分配,那么代码也适用于大型数据集
最后有人可以告诉我在AVX中使用对齐内存是否有任何显着的性能提升。
编辑:经过根据此post的一些研究后,它表示new
从免费商店分配内存,malloc()
从堆中分配内存。在这里,我超过了最大堆大小_aligned_malloc()
返回errno
12这意味着ENOMEM
在这种情况下,有人可以告诉我一个解决此问题的方法。
答案 0 :(得分:2)
我似乎在试图找到2000*1300*17*17*4
32 bytes
元素。这意味着您尝试分配96 GB而系统只有12 GB内存。
由于new
正在运行,但malloc似乎您的new
的本地实现似乎能够分配大量的虚拟内存 。 Malloc从堆中分配,这意味着它通常仅限于您拥有的物理内存量。这就是它失败的原因。
由于数据集大于主内存,您可能希望使用mmap
来分配内存,mmap
将文件映射到虚拟内存,使其可以访问,就像它在物理内存中一样(但它只会部分缓存在内存中)。我不确定它是否有保证,但2000*1300*17*17*4
通常在最佳页面大小边界(几乎总是4096字节)上对齐。
无论如何,由于磁盘方式比RAM慢,因此会造成巨大的性能损失。这是非常严重的,使用AVX可能根本不会加速任何事情。
在现代硬件上(比如英特尔的Haswell,我认为)这取决于您的访问模式。在内存顺序上迭代数组时,未对齐访问应该几乎没有性能开销(每个缓存行仍将只加载一次)。如果以随机顺序访问它,则通常会跨越 64字节缓存行边界。这意味着您的处理器必须将2行加载到缓存中并从缓存中删除2行而不是仅删除一行。虽然在某些情况下这可能是一个严重的问题,但是磁盘会减慢速度,以至于你几乎没有注意到这一点。
您给出数组大小(auto x = new __m256[2000][1300][17][17][4]
)的方式表明您使用的是多维数组(例如input::-ms-clear, input::-ms-reveal {
display: none;
}
)。所以有些蠢货:
您可以尝试展平数组并自己进行更复杂的索引计算,以减少需要的内存量。如果你完全适合你的RAM,你可以开始优化你的代码(使用AVX和/或对齐的内存)。
“所有驱动器的总页面文件大小为15247MB”表明您实际上只使用 96 GB 的部分内容,因此可能有一种方法可以进一步减少使用量
在这种情况下,您可能还想询问另一个关于如何通过更多信息来减少内存使用量的问题。