あなたのコードは CPU の Rambo です - その最悪の悪夢:
- バイトアクセス。前述のように、ARMはメモリからバイトを読み取るのが非常に遅い
- ランダムアクセス。その性質上、すでに急激なパフォーマンスの低下に加えて、絶対に不要な 2 つの乗算/加算操作。
簡単に言えば、間違っている可能性があるものはすべて間違っています。
私を無礼と呼ばないでください。代わりに私をあなたの天使にさせてください。
まず、動作する NEON バージョンを提供します。次に、最適化された C バージョンで、何が間違っていたかを正確に示します。
少し時間をください。私は今すぐ寝なければなりません、そして明日は重要な会議があります。
ARMのアセンブリを学びませんか?x86 アセンブリよりもはるかに簡単で便利です。また、C プログラミング機能も大幅に向上します。強く推奨する
ちゃあ
================================================== ============================
OK、これは ARM アセンブリを念頭に置いて C で書かれた最適化されたバージョンです。
ピッチと a_lenx の両方が 4 の倍数でなければならないことに注意してください。そうでないと、適切に動作しません。
このバージョンでは、ARM アセンブリを最適化する余地はあまりありません。(NEON は別の話です - 近日公開)
変数の宣言、ループ、メモリ アクセス、および AND 演算の処理方法をよく見てください。
また、最良の結果を得るには、この関数が Thumb ではなく ARM モードで実行されるようにしてください。
unsigned int compare(unsigned int *a, unsigned int a_pitch,
unsigned int *b, unsigned int b_pitch, unsigned int a_lenx, unsigned int a_leny)
{
unsigned int overlap =0;
unsigned int a_gap = (a_pitch - a_lenx)>>2;
unsigned int b_gap = (b_pitch - a_lenx)>>2;
unsigned int aval, bval, xcount;
do
{
xcount = (a_lenx>>2);
do
{
aval = *a++;
// ldr aval, [a], #4
bval = *b++;
// ldr bavl, [b], #4
aval &= bval;
// and aval, aval, bval
if (aval & 0x000000ff) overlap += 1;
// tst aval, #0x000000ff
// addne overlap, overlap, #1
if (aval & 0x0000ff00) overlap += 1;
// tst aval, #0x0000ff00
// addne overlap, overlap, #1
if (aval & 0x00ff0000) overlap += 1;
// tst aval, #0x00ff0000
// addne overlap, overlap, #1
if (aval & 0xff000000) overlap += 1;
// tst aval, #0xff000000
// addne overlap, overlap, #1
} while (--xcount);
a += a_gap;
b += b_gap;
} while (--a_leny);
return overlap;
}