代码之家  ›  专栏  ›  技术社区  ›  avgn

我应该和mkl_malloc保持什么样的一致性?

  •  2
  • avgn  · 技术社区  · 6 年前

    功能 mkl_malloc 类似于 malloc 但是有一个额外的 alignment 争论。这是原型:

    void* mkl_malloc (size_t alloc_size, int alignment);
    

    我注意到不同的表演有不同的价值 对齐 . 除了试错,还有没有 规范的或记录的 确定最佳价值的方法 对齐 ? 即正在使用的处理器、正在调用的函数、正在执行的操作等。

    这个问题广泛适用于任何使用MKL的人,所以我很惊讶它不在参考手册中。

    更新:我试过 mkl_sparse_spmm 并没有注意到将对齐设置为2到1024字节的幂的性能有显著差异,之后性能趋于下降。我用的是英特尔至强E5-2683。

    3 回复  |  直到 6 年前
        1
  •  3
  •   Qubit    6 年前

    只有当可以使用SSE/AVX指令时,对齐才会影响性能—当您希望对一系列元素应用相同的操作时,使用数组进行操作时通常会出现这种情况。

    一般来说,您需要根据CPU选择对齐方式,如果它支持AVX2,它有256bit寄存器,那么您需要32字节对齐,如果它支持AVX512,那么64字节将是最佳的。

    为此, mkl_malloc 将确保与指定的值对齐,但是,显然,如果数据是32字节对齐的,那么它们也将与(16、8、4…)字节边界对齐。呼叫的目的是确保情况始终如此,从而避免任何潜在的并发症。

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

    相反,使用 malloc 为1GB的数据提供16字节的对齐,为1KB提供32字节的对齐,无论操作系统给我什么,对对齐没有任何偏好。

    所以使用 马洛克 这是有道理的,因为它可以确保你得到你想要的一致性。但是,这并不意味着您应该将该值设置得太大,这只会导致浪费内存,并可能使您面临更多的缓存未命中。

    简而言之,您希望数据与CPU中向量寄存器的大小对齐,以便可以使用相关扩展。使用 马洛克 使用某些对齐参数可确保对齐 至少 但是,这个值可能更大。它应该用于确保数据按您所需的方式对齐,但绝对没有理由对齐到1MB。

        2
  •  1
  •   Kaveh Vahedipour    6 年前

    唯一的原因是,不管您的输入是什么,指定对齐都不会带来任何损失/收益,因为无论您键入什么,都会获得与机器对齐的内存。所以在你的处理器上,它支持 AVX ,无论您的输入是什么,您总是得到32字节对齐的内存。

    您还将看到,无论您选择哪种对齐值,内存地址 mkl_malloc ,返回值是可除的32对齐。或者您可以测试低级别的intrisic,比如 _mm256_load_pd ,当使用非32字节对齐的地址时,这将导致seg故障never seg fault。

    一些小细节:OSX总是给你32字节的地址,当你分配一块内存时堆/堆栈独立,而Linux总是给你在堆上分配时对齐的内存。堆栈在Linux上是一个运气问题,但是小矩阵已经超过了堆栈分配的限制。我不了解Windows上的内存分配。

    当我为我的 numerics library 我用的地方 std::vector<typename T, alignment A> 对于内存分配和较小的矩阵测试,Linux上有时会出现seg故障。

    TLDR公司 :您的校准输入被有效地丢弃,并且您将获得机器校准。

        3
  •  1
  •   abjoshi - Reinstate Monica    6 年前

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

    说到你的具体问题,重要的是要说明你到底在为什么分配内存?哪个硬件访问内存?例如,我曾经使用过DMA引擎,它要求源地址与每个事务传输大小对齐(其中xfer size=4、8、16、32、128)。我还研究了向量寄存器,在这里有一个128位对齐负载是明智的。

    总结一下:这要看情况。