我必须在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)];
}}}
}
答案 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值也是有益的。