我必须在C中实现两个矩阵之间的Khatri-Rao积。从数学上讲,这是一列主要的数据访问,我不能改变。但是如果我使用preload(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)];
}}}
}
最佳答案
预加载指令也有自己的成本。通常,您希望在实际阅读之前预加载,并仔细配置。
也就是说,如果这是gcc或clang,那么最好使用__builtin_prefetch
而不是显式内联asm,因为它将编译为支持它的目标(ARMv5TE和更高版本)的PLD,否则将是无害的。我发现这篇博客文章展示了一些实际使用的示例:
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值是有益的。
关于c - 在C语言中的ARMv7中预取,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37040006/