我应该与mkl_malloc对齐的值是多少?

时间:2018-08-03 01:06:10

标签: c linear-algebra memory-alignment blas intel-mkl

函数1|| 1类似,但具有一个额外的mkl_malloc参数。这是原型:

malloc

我注意到alignment的值不同时的表现也不同。除了反复试验之外,还可以通过规范或有记录的方法来确定void* mkl_malloc (size_t alloc_size, int alignment); 的最佳值吗?即正在使用处理器,正在调用功能,正在执行操作等。

该问题广泛适用于使用MKL的任何人,因此我很惊讶它没有出现在参考手册中。

更新:我尝试使用alignment,但没有注意到将对齐方式设置为2的幂(最多1024字节)时性能上的显着差异,此后性能趋于下降。我正在使用Intel Xeon E5-2683。

3 个答案:

答案 0 :(得分:2)

仅当可以使用SSE / AVX指令时,对齐方式才会影响性能-在对数组进行操作时,这通常是正确的,因为您希望对一系列元素应用相同的操作。

通常,您要基于CPU选择对齐方式,如果它支持具有256位寄存器的AVX2,则需要32字节对齐,如果它支持AVX512,则64字节将是最佳选择。

为此,mkl_malloc将保证与您指定的值对齐,但是,显然,如果数据是32字节对齐的,则它们也将对齐为(16、8、4 ...)字节边界。致电的目的是确保情况始终如此,从而避免任何潜在的麻烦。

在我的机器上(运行于i7 6700K的Linux内核4.17.11),mkl_malloc的默认对齐方式似乎是128字节(对于足够大的数组,如果它们太小,则值似乎是32KB ),换句话说,任何小于该值的值都不会影响对齐,但是我可以输入256,并且数据将对齐到256字节边界。

相比之下,使用malloc可以为我提供1GB数据的16字节对齐方式和为1KB的32字节对齐方式,而无论操作系统如何,我对对齐方式都毫无偏爱。

因此使用mkl_malloc是有意义的,因为它可以确保获得所需的对齐方式。但是,这并不意味着您应该将该值设置得太大,这只会导致您浪费内存,并可能使您面临更多的高速缓存未命中。

简而言之,您希望数据与CPU中矢量寄存器的大小对齐,以便可以使用相关的扩展名。将mkl_malloc与某些参数结合使用,可以保证至少该值与该值对齐,但是可以更多。应该使用它来确保数据按照所需的方式对齐,但是绝对没有充分的理由将数据对齐到1MB。

答案 1 :(得分:1)

唯一的原因,无论您输入什么内容,指定对齐都不会带来任何代价/收益,是因为无论您键入什么内容,都可以获得机器对齐的内存。因此,在支持AVX的处理器上,无论您输入什么内容,您总是可以获得32字节对齐的内存。

您还将看到,无论要使用什么对齐值,mkl_malloc返回的内存地址都是32对齐的整数。另外,您可以测试使用低_mm256_load_pd这样的低级特性,如果使用非32字节对齐的地址,则永远不会出现段错误。

一些次要细节:OSX始终为您提供32字节地址,当您分配大块内存时与堆/堆栈无关,而Linux在分配给堆时始终为您提供对齐的内存。在Linux上,堆栈是个运气问题,但是您已经用较小的矩阵大小超出了堆栈分配的限制。我对Windows上的内存分配不了解。

当我为numerics library编写测试时发现了后者,其中我使用std::vector<typename T, alignment A>进行内存分配,而较小的矩阵测试有时在Linux上出现段错误。

TLDR :您的对齐输入已被有效丢弃,并且无论如何都获得了机器对齐。

答案 2 :(得分:1)

我认为对齐没有“最佳”值。取决于您的体系结构,对齐通常是硬件强制执行的属性,主要是出于优化的原因。

谈到您的特定问题,重要的是声明您到底要为其分配内存?哪个硬件访问内存?例如,我使用DMA引擎,要求将源地址与每个事务传输大小(其中xfer大小= 4、8、16、32、128)对齐。我还与矢量寄存器一起工作,在这种情况下,最好有128位对齐的负载。

总结:这取决于。