SVE 2(スケーラブルなベクトル拡張版2)-研究室6パート2


導入


SVE 2(スケーラブルなベクトル拡張版2)のパート2に戻ってください.あなたがこのポストが何であるかについてわからないならば、あなたはより良い考えがあるのを見ることができます.

SVE 2を適応するための変換のためのソースコード


#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "vol.h"

int16_t scale_sample(int16_t sample, int volume) {

        return ((((int32_t) sample) * ((int32_t) (32767 * volume / 100) <<1) ) >> 16);
}

int main() {
        int             x;
        int             ttl=0;

// ---- Create in[] and out[] arrays
        int16_t*        in;
        int16_t*        out;
        in=(int16_t*) calloc(SAMPLES, sizeof(int16_t));
        out=(int16_t*) calloc(SAMPLES, sizeof(int16_t));

// ---- Create dummy samples in in[]
        vol_createsample(in, SAMPLES);

// ---- This is the part we're interested in!
// ---- Scale the samples from in[], placing results in out[]
        for (x = 0; x < SAMPLES; x++) {
                out[x]=scale_sample(in[x], VOLUME);
        }

// ---- This part sums the samples.

        for (x = 0; x < SAMPLES; x++) {
                ttl=(ttl+out[x])%1000;
        }

// ---- Print the sum of the samples.

        printf("Result: %d\n", ttl);

        return 0;

}
あなたが言うことができるように、これはアルゴリズム選択に関してvoll 1です.
なお、Vol 1は固定小数点演算を利用する.これは、整数と浮動小数点の間で繰り返し鋳造するコストを回避します.

変換


コンパイラオプション


ほとんどのコンパイラはARMv 9システムの特定のターゲットを持っていません.したがって、SVE 2命令を含むコードをビルドするには、SUV 2命令を理解しているARMD 8プロセッサのコードを発行するように、コンパイラに指示する必要がありますGCCコンパイラでは、これは
私たちは、コンパイラが、それが私たちがGCCバージョン11でautovectorizerを起動する必要があることをするためにSVE 2を理解させるためにARMD 8 Aプロセッサのためにコードを放出するように指示しなければなりません、我々
gcc -O3 -march=armv8-a+sve2 
我々のケースでは、我々は第1巻で働いています
gcc -o3 -march=armv8-a+sve2 vol1.c vol_createsample.c -o vol1
次に,qemuユーザモードシステムをエミュレートしてプログラムを実行できる.これはSVE 2命令を捕捉し、それらをハードウェアでエミュレートします.一方、ARV 8 A命令をハードウェアに直接実行します.
qemu-aarch64 ./vol1

結果:



変換コード


.arch armv8-a+sve2
        .file   "vol1.c"
        .text
        .align  2
        .p2align 4,,11
        .global scale_sample
        .type   scale_sample, %function
scale_sample:
.LFB24:
        .cfi_startproc
        lsl     w2, w1, 15
        mov     w3, 34079
        sub     w1, w2, w1
        movk    w3, 0x51eb, lsl 16
        sxth    w0, w0
        smull   x3, w1, w3
        asr     x3, x3, 37
        sub     w1, w3, w1, asr 31
        lsl     w1, w1, 1
        mul     w0, w1, w0
        lsr     w0, w0, 16
        ret
        .cfi_endproc
.LFE24:
        .size   scale_sample, .-scale_sample
        .section        .rodata.str1.8,"aMS",@progbits,1
        .align  3
.LC0:
        .string "Total Time: %2.9f\n"

変換コードの理解


SVE 2命令


 .cfi_startproc
        lsl     w2, w1, 15
        mov     w3, 34079
        sub     w1, w2, w1
        movk    w3, 0x51eb, lsl 16
        sxth    w0, w0
        smull   x3, w1, w3
        asr     x3, x3, 37
        sub     w1, w3, w1, asr 31
        lsl     w1, w1, 1
        mul     w0, w1, w0
        lsr     w0, w0, 16
        ret
        .cfi_endproc

対応するCコード


return ((((int32_t) sample) * ((int32_t) (32767 * volume / 100) <<1) ) >> 16);
  • ' movk w 3 , 0 x 51 eb , lsl 16 'にはLSL 16命令が含まれており、16ビットで左シフトされることを示している.
  • ' sxth 'は、レジスタw 0に自身の最下位要素に署名するよう指示します.
  • ' Smull X 3 , W 1 , W 3 'は' volume 'の値の乗算を32767で示す.
  • ' LSL W 1 , W 1 , 1 'は、最後に1ビットシフトすることを指す.
  • ' MUL W 0 , W 1 , W 0 'は、サンプルを符号付き32ビット整数に乗算する結果を変えます.
  • ' lsr w 0 , w 0 , 16 'は最終結果の整数のビットを16回右シフトする.
  • 結論


    ボリューム調整アルゴリズム(voll 1)へのsve 2命令を実験した.SVE 2は現時点では非常に新しいので、実際にはそれのためのシステムを開発しています.そして、プログラムを実行するためにエミュレータを使用しなければなりません.アセンブリコードのSVE 2パフォーマンスをテストする方法を見つけることができませんでした.
    私が見つけたラボの中で最も挑戦的な部分は、CコードをSVE 2命令に変換した後で、SVE 2からの指示を元のCファイルのコードと関連づける試みでした.
    ソース:SVE2