在C中的ARMv7中预取

时间:2016-05-04 23:49:53

标签: c performance caching memory arm

我必须在C中的2个矩阵之间实现Khatri Rao产品。数学上这是数据的主要访问权限,我不能改变它。但是,如果我使用预加载(ARMv7中的PLD指令)来预取每个下一个循环数据将解决性能问题,而不是使用行主要数据访问。

如果是,如何正确预加载?

请检查下面的预载代码,

void khatrirao_pref(double *C, double *A, double *B,
                  int nmax, int mmax, int pmax)
 {
  int i,k,l;
  for (i=0;i<nmax;i++)
    {
    for (k=0;k<mmax;k++)
      {
        asm("PLD [%0]\n\t" :: "r" (A+i+((nmax+1)*k)));       
      for (l=0;l<pmax;l++)
    {
            asm("PLD [%0]\n\t" :: "r" (B+i+((nmax+1)*l)));
           C[i+(nmax*((k*pmax)+l))]=A[i+(nmax*k)]*B[i+(nmax*l)];
    }}}
 }

1 个答案:

答案 0 :(得分:4)

预加载指令也有自己的成本。通常情况下,您希望在实际阅读之前预先加载,并仔细分析。

话虽如此,如果这是gcc或clang,你最好使用__builtin_prefetch而不是显式内联asm,因为它会编译为支持它的目标的PLD(ARMv5TE及更高版本) ,否则无害。我发现这篇博文显示了一些实际用法的例子:

http://www.naftaliharris.com/blog/2x-speedup-with-one-line-of-code/

这也是了解PLD用法的一个非常有用的链接:

http://infocenter.arm.com/help/topic/com.arm.doc.faqs/ka13544.html

请注意,此页面显示有时使用PLD会有不利之处。我的猜测是,你至少不想在你的内循环中发出它。你一定要审判不同的案件。

根据最常见的矩阵大小,您可能会发现特殊情况下某些nmax / mmax值也是有益的。