1

Neon 組み込み関数を使用して ARM A8 プロセッサ用に最適化された内積を作成しようとしていますが、少し問題があります。まず、これを実装しているライブラリはありますか?私のコードは機能しているように見えますが、実行時にいくつかの静かなエラーが発生します - 私の推測では、最適化されていないコードと比較して精度がわずかに低下しているためです。私がやろうとしていることを達成するためのより良い方法はありますか? 助けや提案があればとても感謝しています。前もって感謝します。

この特定の内積は、32 ビット float * 32 ビット float 複合体です。

最適化されていないコードは次のとおりです。

    double sum_re = 0.0;
    double sum_im = 0.0;
    for(int i=0; i<len; i++, src1++, src2++)
    {
            sum_re += *src1 * src2->re;
            sum_im += *src1 * src2->im;
    }

これが私の最適化されたバージョンです:

    float sum_re = 0.0;
    float sum_im = 0.0;

    float to_sum_re[4] = {0,0,0,0};
    float to_sum_im[4] = {0,0,0,0};

    float32x4_t tmp_sum_re, tmp_sum_im, source1;
    float32x4x2_t source2;
    tmp_sum_re = vld1q_f32(to_sum_re);
    tmp_sum_im = vld1q_f32(to_sum_im);

    int i = 0;

    while (i < (len & ~3)) {
            source1 = vld1q_f32(&src1[i]);
            source2 = vld2q_f32((const float32_t*)&src2[i]);

            tmp_sum_re = vmlaq_f32(tmp_sum_re, source1, source2.val[0]);
            tmp_sum_im = vmlaq_f32(tmp_sum_im, source1, source2.val[1]);

            i += 4;
    }
    if (len & ~3) {
            vst1q_f32(to_sum_re, tmp_sum_re);
            vst1q_f32(to_sum_im, tmp_sum_im);

            sum_re += to_sum_re[0] + to_sum_re[1] + to_sum_re[2] + to_sum_re[3];
            sum_im += to_sum_im[0] + to_sum_im[1] + to_sum_im[2] + to_sum_im[3];
    }

    while (i < len)
    {
            sum_re += src1[i] * src2[i].re;
            sum_im += src1[i] * src2[i].im;
            i++;
    }
4

3 に答える 3

5

iOS を使用している場合は、Accelerate フレームワークで vDSP_zrdotpr を使用します。(vDSP_zrdotpr は、実数ベクトルと複素数ベクトルのドット積を返します。実数から実数または複素数から複素数など、他のバリアントがあります。)

もちろん、精度は失われます。最適化されていないコードは倍精度の合計を累積しますが、NEON コードは単精度の合計を累積します。

精度を変更しなくても、異なる順序で浮動小数点演算を実行すると異なる丸め誤差が生成されるため、結果は異なると予想されます。(これは整数にも当てはまります。7/3*5 を計算すると 10 になりますが、5*7/3 は 11 です。)

エラーを減らして浮動小数点演算を行うアルゴリズムがあります。ただし、高性能のドット積を実行するには、通常、得られるものに固執します。

1 つのオプションは、倍精度 NEON 命令で演算を行うことです。もちろん、これは単精度 NEON ほど高速ではありませんが、スカラー (非 NEON) コードよりは高速です。

于 2012-07-11T16:50:46.387 に答える
0

その他の実装としては、ARM の NEON OpenMAX DL 実装があります。http://www.arm.com/community/multimedia/standards-apis.phpからリンクされています。

ダウンロードには登録が必要で、形式は RVCT アセンブラーですが、NEON の使用方法の一連の例 (ドット積の実装を含む) を見るには、かなり良いです。

于 2012-07-14T14:33:43.600 に答える