アルゴリズムの一部を C から ARM アセンブラー (NEON 命令を使用) に変換しましたが、元の C コードよりも 2 倍遅くなりました。どうすればパフォーマンスを向上させることができますか?
ターゲットは ARM Cortex-A9 です。
このアルゴリズムは、配列から 64 ビット値を読み取ります。この値から 1 バイトが抽出され、別のテーブルのルックアップ値として使用されます。この部分は約 10 回実行され、結果の各テーブル値が他の値と XOR 演算され、最終結果が別の配列に書き込まれます。
このようなもの:
result[i] = T0[ GetByte0( a[i1] ) ] ^ T1[ GetByte1( a[i2] ) ] ^ ... ^ T10[ (...) ];
私のアプローチでは、配列「a」全体を Neon Registers にロードしてから、右のバイトをアームレジスタに移動し、オフセットを計算してから、テーブルから値をロードします。
vldm.64 r0, {d0-d7} //Load 8x64Bit from the input array
vmov.u8 r12, d0[0] //Mov the first Byte from d0 into r12
add r12, r2, r12, asl #3 // r12 = base_adress + r12 << 3
vldr.64 d8, [r12] // d8 = mem[r12]
.
.
.
veor d8, d8, d9 // d8 = d8 ^ d9
veor d8, d8, d10 // d8 = d8 ^d10 ...ect.
ここで、r2 はルックアップ テーブルのベース アドレスを保持します。
adress = Table_adress + (8* value_fromByte);
このステップ (最初のロードを除く) は 100 回ほど実行されます。なぜこれはとても遅いのですか?
また、 「vld」、「vldr」、および「vldm」の違いは何ですか- そしてどれが最速です。Neon レジスタ内でのみオフセット計算を実行するにはどうすればよいですか? ありがとうございました。