Cで2つの行列の間にKhatri Raoプロダクトを実装する必要があります。数学的には、これはデータの主なアクセスであり、変更できません。しかし、プリロード(ARMv7でPLD命令)を使用して次のループの各データをプリフェッチすると、行の主なデータアクセスを使用する代わりにパフォーマンスの問題が解決されます。C言語でのARMv7でのプリフェッチ
「はい」の場合は正しくプリロードするにはどうすればよいですか?
以下の私のプリロード・コードを確認してください、
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)];
}}}
}
いつもカラムメジャー順を使うつもりなら、あなたは 'A [row] [col]'を持っていた配列インデックスの意味を逆にしてカラムを行と行として扱うことができるかどうかを考えてみましょう。 '' [col] [row] '。これにより、メモリ・シーケンスでデータにアクセスすることによるキャッシュの利点が得られます。それは軽く行うことではなく、非常に注意深く測定してテストすることです。 –
@JonathanLefflerこんにちはJonathan、返事ありがとうございます。しかし、私はそうすることはできません。私は厳密に主要なアクセスをcollumnにとどまらなければなりません。私は内側の方程式や3つのループの順序や配列の次元を変更することはできません。私はプリフェッチを使って、同じ列のAとBの次のループデータを得ることができます。私はこれが奇妙なことを知っています。私は尋ねています。どう思いますか ? – karnajitsen
あなたのメモリアクセスパターンで "穀物と反対"に行くことは間違いなく性能を損なうでしょう。より良い計画は、このコードに到達する前に、配列全体をキャッシュにプリフェッチすることです。書かれているように、先読みは役に立たないでしょう。あなたはCPUにヒントを与え、実際に読書をする時間を与える必要があります。 – BitBank