重力に対するアーキテクチャ固有のC/C++イントニンシクスの移植


C 64 C +アプリケーションのX 64からGravitonへの移行は、ARMアーキテクチャのソースコードを再コンパイルする必要があります.“単純な再コンパイル”のマーケティングメッセージは、多くの時間の作品が、必ずしもではない.SIMD拡張はX 64からC/C++アプリケーションを重力子に移植する際に遭遇する共通の障壁の一つです.今日、Gravitonのコンパイル時にアーキテクチャ固有の問題に遭遇したらどうするか見てみましょう.私たちはあなたのコードをコンパイルして実行するための計画が続く短い背景から始めます.
本質は何か
まず、イントインサイトについての小さな背景.イントインシクスは、コンパイラに組み込まれ、ライブラリの一部ではない関数です.関数呼び出しのように見えますが、実際の関数呼び出しを必要としません.コンパイラが本質的に遭遇するとき、それは直接命令のシーケンスを代入します.イントリンシクスは、C/C++からの直接マッピングを必要としない特別な命令にアクセスするために使用されることが多い.
イントリングスの1つの使用は、改善されたアプリケーションパフォーマンスのためにC/C +から直接SimD(単一命令、複数のデータ)命令にアクセスすることです.アセンブリーはアセンブリ言語と比較して作業が楽になりますが、ソースコードを新しいアーキテクチャに移植するときにはしばしば問題を起こします.この移植性バリアは、再コンパイルが必要とされたすべてであると考えていたなら、あまり魅力的ではありません.あなたがコードをよく知らないならば、状況はより悪いかもしれません.
インテルSimidArm NEON SIMD命令は、単一の命令で複数の計算を実行することによって、プロセッサ・スループットを増やします.長年にわたって、インテルとARMは様々なSIMD拡張を導入しました.ネオンはARM Cortex - R、Cortex - A、およびNETNERSEプロセッサの多くで使用されます.
あなたがSIMD命令に精通していないならば、利用できる多数のチュートリアルがあります.SIMDハードウェアをプログラムするには、一般的に3つの方法があります.
  • C/C++コンパイラはSIMD命令を使用する機会を認識し、自動的に挿入します
  • C/C++ソースコードから直接Simd命令にアクセスするための本質
  • アセンブリプログラミング
  • SSE 2 neonとは何か
    The sse2neon project C/C++アプリケーションを重力式でコンパイルして実行する簡単な方法です.SSE 2 neonヘッダーファイルは、ソースコード変更が必要でないように、x 64 intrinsicsのためにネオン実現を提供します.各々の関数呼び出し(内在的な)は単にネオン命令で取り替えられて、ちょうど重力子に取り組みます.
    以下はSSE 2 NEONを使用するプロセスを示す小さな例です.ソースコードはshort course titled Efficient Vectorisation with C++ そして、著作権(c)クリストファーWoodsCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License .
    #include <iostream>
    
    #ifdef __SSE2__
      #include <emmintrin.h>
    #else
      #warning SSE2 support is not available. Code will not compile
    #endif
    
    int main(int argc, char **argv)
    {
        __m128 a = _mm_set_ps(4.0, 3.0, 2.0, 1.0);
        __m128 b = _mm_set_ps(8.0, 7.0, 6.0, 5.0);
    
        __m128 c = _mm_add_ps(a, b);
    
        float d[4];
        _mm_storeu_ps(d, c);
    
        std::cout << "result equals " << d[0] << "," << d[1]
                  << "," << d[2] << "," << d[3] << std::endl;
    
        return 0;
    }
    
    最初に、私たちは、1つの参照を参照してください.ヘッダーファイル.これらはアーキテクチャ固有の拡張機能であり、Call MMで始まる関数コールはインテルSSE intrinsicsです.
    ソースコードファイル名がSSEであると仮定します.上記のコードは、X 64アーキテクチャでコンパイルされ、以下のコマンドで実行されます.
    $ g++ -O2 -msse2 --std=c++14 sse.cpp -o sse
    $ ./sse
    
    このアプリケーションをコンパイルし、重力の上で実行する3つの手順があります.
  • ARMアーキテクチャのSSE固有のヘッダーファイルの使用状況を調整する
  • sse 2 neonを含みます.イントロンをネオン命令に写像するH
  • ARMアーキテクチャ用のG +コンパイラフラグを変更する
  • これが新しいプログラムです.唯一の変更はインクルードファイルに関連します.
    #include <iostream>
    
    #ifdef __SSE2__
      #include <emmintrin.h>
    #else
      #ifdef __aarch64__
        #include "sse2neon.h"
      #else
        #warning SSE2 support is not available. Code will not compile
      #endif
    #endif
    
    int main(int argc, char **argv)
    {
        __m128 a = _mm_set_ps(4.0, 3.0, 2.0, 1.0);
        __m128 b = _mm_set_ps(8.0, 7.0, 6.0, 5.0);
    
        __m128 c = _mm_add_ps(a, b);
    
        float d[4];
        _mm_storeu_ps(d, c);
    
        std::cout << "result equals " << d[0] << "," << d[1]
                  << "," << d[2] << "," << d[3] << std::endl;
    
        return 0;
    }
    
    新しいファイルがneonであると改名されると仮定します.CPPこのバージョンは、以下のコマンドを使用してARMアーキテクチャでコンパイルおよび実行できます.g +オプションは、Gravity 2に推奨されるオプションです.
    $ g++ -O2 -march=armv8.2-a+fp16+rcpc+dotprod+crypto --std=c++14 neon.cpp -o neon
    $ ./neon
    
    どちらの場合もプログラム出力は以下の通りです:
    result equals 6,8,10,12
    
    他に何が重力に移植するために利用可能ですか?
    私はいつも人を指すGetting started with AWS Graviton 良い場所として有用な移行情報やその他の有用なヒントを見つけること.
    役に立つかもしれないもう一つのツールはaarch64 Porting Advisor . アーキテクチャ固有のコードを識別する簡単な方法です.移植アドバイザーは上記の単純な例のために必要ではありません、しかし、より大きいプロジェクトに深く隠れているアーキテクチャ固有のintrinsicsがあるならば、それは彼らを見つけるのを助けることができます.
    portingアドバイザーを使用するには、以下のコマンドを使用してインストールします.
    $ git clone https://github.com/arm-hpc/porting-advisor.git
    $ cd porting-advisor
    $ sudo python3 setup.py install
    
    解析するソースコードを持つディレクトリを指定して、移植アドバイザーを実行します.たとえば、オープンソースのKasmVNCプロジェクトで試してみると、以下のコマンドを使用します.
    $ git clone https://github.com/kasmtech/KasmVNC.git
    $ porting-advisor KasmVNC 
    | Elapsed Time: 0:00:00                                                                                                              
    413 files scanned.
    KasmVNC/common/rfb/scale_sse2.cxx: 55 other issues
    KasmVNC/common/rfb/scale_sse2.cxx:74 (SSE2_halve): architecture-specific intrinsic: _mm_loadu_si128
    KasmVNC/common/rfb/scale_sse2.cxx:75 (SSE2_halve): architecture-specific intrinsic: _mm_loadu_si128
    KasmVNC/common/rfb/scale_sse2.cxx:62 (SSE2_halve): architecture-specific intrinsic: _mm_set_epi32
    KasmVNC/common/rfb/scale_sse2.cxx:63 (SSE2_halve): architecture-specific intrinsic: _mm_set_epi32
    KasmVNC/common/rfb/scale_sse2.cxx:64 (SSE2_halve): architecture-specific intrinsic: _mm_set_epi32
    KasmVNC/common/rfb/scale_sse2.cxx:61 (SSE2_halve): architecture-specific intrinsic: _mm_setzero_si128
    KasmVNC/common/rfb/scale_sse2.cxx:78 (SSE2_halve): architecture-specific intrinsic: _mm_unpackhi_epi8
    KasmVNC/common/rfb/scale_sse2.cxx:80 (SSE2_halve): architecture-specific intrinsic: _mm_unpackhi_epi8
    KasmVNC/common/rfb/scale_sse2.cxx:77 (SSE2_halve): architecture-specific intrinsic: _mm_unpacklo_epi8
    KasmVNC/common/rfb/scale_sse2.cxx:79 (SSE2_halve): architecture-specific intrinsic: _mm_unpacklo_epi8
    
    Use --output FILENAME.html to generate an HTML report.
    
    移植アドバイザーはディレクトリをスキャンして、アーキテクチャ特有の拡張をすぐに指摘します.詳細については、使用方法の説明を参照してください.
    概要
    AWSのGravitonプロセッサは、多くのワークロードのための最高の価格パフォーマンスを提供する64ビットアームneoverseコアを使用してAmazon Webサービスによってカスタム構築されています.私は私がReで話をした人々の数によって愉快に驚きました:成功した2021は、GRAND 2にアプリケーションを移行して、結果に満足していました.アーキテクチャ固有のイントインシクスは1つだけ可能な移行障壁ですが、通常は克服することができます.
    私たちは他のAWSの重力のプロセッサにアプリケーションを移行から停止している知ってみましょう.