GPU Dranoは、GPUプログラムの静的分析ツールです。 GPU Dranoの分析の1つは、CUDAコードで無視されていないメモリアクセスを見つけることです。 GPU Dranoによってサポートされている他の分析は、GPUプログラムのブロックサイズの独立性を証明する分析です。
最新のGPUSスレッドをワープにバンドルします。ワープ内のすべてのスレッドは、ロックステップで操作を実行します。メモリが隣接している場合、またはメモリが十分に近い場合、さまざまなメモリの位置へのメモリアクセスを単一の負荷/ストアに合体させることができます。ワープによってアクセスされるメモリが遠く離れている場合、メモリトランザクションを完了するには複数の負荷/ストアが必要であり、アクセスは無視されていると言います。
GPUカーネルは、ブロックサイズのスレッドの総数を同じに保ちながらブロックサイズを変更する場合、プログラムの機能を破らない場合、ブロックサイズの独立と言われています。これは、プログラムのパフォーマンスを改善するためによく使用されるGPUプログラムでの正しいブロックサイズのチューニングに不可欠です。
また、発生していないアクセスを特定するための動的な分析も実装しました。このリポジトリで利用できます。
GPU Dranoは、GoogleのオープンソースCUDA実装: gpuccを使用して、LLVMのコンパイラパスとして実装されています。したがって、DranoはLLVMとしっかりと結合されています。
DranoにはLLVMバージョン6.0以降が必要です。また、NvidiaのCuda Toolkit(バージョン7.5以降)が必要です。 Ubuntu 16.04 LTSでテストされていますが、ほとんどの既存のLinuxシステムで動作するはずです。
静的分析自体はGPUを必要としません。ただし、プログラムを実行し、動的なAnlaysisを実行するには、Nvidia GPUと互換性のあるドライバーが必要です。詳細については、NVIDIAのシステム要件を確認してください。
アルゴリズムと設計の選択の詳細は、次の論文にあります。
プロジェクトに含まれているスクリプトinstallnrun.sh 、UbuntuシステムでGPU Dranoを構築および実行するために必要な手順を詳述しています。スクリプトを実行するには、
ROOT_DIRダウンロードしたフォルダーへのパスに設定します。sh installnrun.sh実行しますこれにより、LinuxシステムにGPU Dranoが自動的にインストールされます。さらに、こちらのアクセスのないアクセス分析をインストールするためのインストール手順について説明します。ブロックサイズの独立性分析のインストール(ブロックサイズの不変性分析とも呼ばれます)も同様に行うことができます。
LLVMを取得する出典:
subversionがインストールされていることを確認してください。 LLVMの最新バージョンをダウンロードしてください:
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
CLANGソースを取得:
現在の作業ディレクトリをllvm/tools/に変更し、SVNリポジトリからclangをご覧ください。
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
GPU DranoをLLVMに追加します:
GPU Dranoのsrc/フォルダーをディレクトリllvm/lib/Transforms/UncoalescedAnalysis in Your Sourceコードにコピーします。
cp -r src/abstract-execution/* llvm/lib/Transforms/UncoalescedAnalysis
cp -r src/uncoalesced-analysis/* llvm/lib/Transforms/UncoalescedAnalysis
これによりllvm/lib/Transforms/UncoalescedAnalysis/というフォルダーが作成されます。 LLVMビルドシステムcmakeにパスを登録する必要があります。したがって、 add_subdirectory(UncoalescedAnalysis) llvm/lib/Transforms/CMakeLists.txtに追加します
サンプルcmakelists.txtファイル:
$> more CMakeLists.txt
add_subdirectory(Utils)
add_subdirectory(Instrumentation)
add_subdirectory(InstCombine)
add_subdirectory(Scalar)
add_subdirectory(IPO)
add_subdirectory(Vectorize)
add_subdirectory(Hello)
add_subdirectory(ObjCARC)
add_subdirectory(Coroutines)
add_subdirectory(UncoalescedAnalysis)
LLVMとGPU Dranoを構築する:
Dranoのルートディレクトリから、 build/ディレクトリを作成します。次に、ディレクトリをbuild/ディレクトリに変更します。 CMAKEがシステムにインストールされていることを確認してください。ここで次のコマンドを実行します。
cmake ../llvm
make
これは、LLVMディレクトリ( ../llvm )へのパスを使用したcmakeです。 cmakeシステムにLLVMを構成します。現在の作業ディレクトリ( build/ )に複数のファイルを生成する必要があります。コマンドはLLVMとDranoをmakeします。
理想的には、llvmが構築に時間がかかるため、nは並行して構築するコアのmake -j Nを使用します。
通知:LLVMビルドは、特にリンクステップで大量のメモリをコンパイルします。 8ギガバイトのRAMがある場合、LLVMは構築に失敗する可能性があります。その場合、 -jオプションなしで再makeできます。これにより、ビルドの失敗した部分が再コンパイルされるだけで、最初から-j使用しないよりも時間を節約できます。
LLVMとGPU Dranoのインストールsudo make installを実行します。これにより、デフォルトの場所(または指定された場所)にライブラリとバイナリをインストールする必要があります。ローカルにインストールされている場合、このガイドは、Bashがパスでコマンドを見つけることができると仮定します。
上記はクイックスタートガイドです。 LLVMに慣れていない場合は、http://llvm.org/docs/gettingstarted.htmlにインストールの詳細をすべて見つけることができます。
スクリプトinstallnrun.sh 、NVIDIAドライバー、Toolkit、およびSDKを構築するプロセスについて簡単に説明します。このスクリプトは、既存のNvidiaドライバーを最優先するリスクを回避するためにコメントアウトされています。静的分析を実行するには、ツールキットとSDKのみが必要であることに注意してください。また、動的分析とCUDAプログラム自体を実行するには、ドライバーと機能するGPUが必要です。
NVIDIAドライバー、CUDA Toolkit、およびSDKをインストールしてください。指示については、NVIDIAインストールガイドを参照してください。
要約すると、最近の人気のあるLinuxディストリビューションを使用する場合は、自動ダウンロードツールを使用して、必要なドライバーとSDKをインストールできるはずです。
既に必要なドライバーとSDKをインストールしている場合は、この手順をスキップできます。これにより、システムが使用できなくなる可能性があるため、既存のドライバーをオーバーライドすることはおそらく良い考えではありません。
clangが必要とする必要なライブラリをインストールするには、G ++-Multilibが必要になる場合があります。
このステップはオプションです。 「Hello World」のような単純なCUDAプログラムは、 clangまたはclang++を使用してコンパイルする必要があります。
clang -x cuda helloWorld.cu
-x cudaオプションは、言語を明示的に述べています。あなたもそれを省略するかもしれません、そして、ClangはこれをCUDAプログラムとして推測します。
注意: Clangのインストールでは、いくつかの内部LLVM関数を見つける必要がない場合があります。もしそうなら、 -lcudartを含める必要がある場合があります。また、 cudart.soの場所を指す必要がある場合があります。
例:
clang -x cuda -L /usr/local/cuda/targets/x86_64-linux/lib/ -lcudart helloWorld.cu
あなたのcudart.soへの道は、システムによって異なる場合があります。
LLVMは、 build/lib/ディレクトリの下で、 LLVMUncoalescedAnalysis.soと呼ばれる共有オブジェクト.soファイルを生成する必要があります。
LLVMコンプライアクclang CUDAプログラムをコンパイルするときに、個別のデバイス(GPUカーネルコード)とホスト(CPUで実行)IRファイルを生成します。 GPU Dranoは、デバイスコードのLLVM IRファイルを分析します。
例として、 gaussianベンチマークのRodiniaカーネルコードを分析しましょう。ディレクトリをrodinia_3.1/cuda/gaussian/に変更します。
最初に、興味のあるコードのLLVM IRファイルを生成しました。
clang++ -S -g -emit-llvm gaussian.cu
生成されたIRのソースコードの位置に関するデバッグ情報を保持するために、デバッグシンボル-gをコンパイルすることに注意してください。これは、LLVM IRからの潜在的な非密集されたアクセスを備えたソースコードの位置を指すために使用されます。
コンパイルは2つのファイルを生成します。
gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll
gaussian.ll
次に、GPU Dranoバイナリへのパスを指定し、実行するパス-interproc-uncoalesced-analysisを指定することにより、LLVMのoptを介して静的分析を実行できます。このパスは、無視されていないアクセスを検出するための介入分析です。コールグラフの最上位の関数の分析から始まり、その後、トポロジ順にカリーの分析を進めます。特定のCalleeを分析する際、すべての発信者のコールコンテキストの結合を考慮します。陽性内分析を実行するには(すべての初期関数引数がスレッドのIDとは無関係であると仮定します)、 -interproc-uncoalesced-analysisではなく、実行されるパス-uncoalesced-analysisを指定します。
opt -load ../../../build/lib/LLVMUncoalescedAnalysis.so -instnamer -interproc-uncoalesced-analysis < gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll > /dev/null 2> gpuDranoResults.txt
opt標準入力からIRファイルを読み取ります。 opt 、それが標準のない独自の出力を書き込み、 /dev/null GPU Dranoの出力にリダイレクトし、ファイルにリダイレクトされる可能性のある標準誤差に書き込まれます。
冗長分析結果(分析情報が注釈されたLLVM IR)を生成するには、追加の-debug-only=uncoalesced-analysisフラグを使用してoptを実行します。
次のコマンドを使用して、プログラムでブロックサイズの独立性分析を実行できます。
opt -load ../../../build/lib/LLVMBlockSizeInvarianceAnalysis.so - -instnamer -always-inline -interproc-bsize-invariance-analysis < gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll > /dev/null 2> gpuDranoResults.txt
発生していないアクセス分析の生成された結果は、各GPUカーネルで潜在的に無視される可能性のあるすべてのアクセスを報告しています。たとえば、 gaussian.cuの分析の結果を以下に示します。
Analysis Results:
Function: _Z4Fan1PfS_ii
Uncoalesced accesses: #2
-- gaussian.cu:295:59
-- gaussian.cu:295:61
Analysis Results:
Function: _Z4Fan2PfS_S_iii
Uncoalesced accesses: #4
-- gaussian.cu:312:38
-- gaussian.cu:312:35
-- gaussian.cu:312:35
-- gaussian.cu:317:23
各結果項目は、ソースコードの潜在的に無視されていないアクセスを指します。たとえば、295行目のm_cudaへのアクセス、gaussian.cuの列59にアクセスFan1()は無視されていません。
同様に、ブロックサイズの独立性分析のために生成された結果は、ブロックサイズの独立したすべてのカーネルを識別します!
ロディニアは、異なるドメインからの22のプログラムで構成されるGPUプログラムの人気のベンチマークスイートです。スイートを分析し、静的分析を使用して111の実際の非密集されていないアクセスを見つけました。結果を再現するために、ここに関連する手順があります。
rodinia_3.1/common/make.configのCudaとDranoの構成を更新します。 NVIDIAツールキットとSDKパスを使用して、 CUDA_DIRとSDK_DIR設定します。 GPU Drano Binary LLVMUncoalescedAnalysis.soへのパスを使用したoptエイリアスを更新します。
ベンチマークディレクトリrodinia_3.1/cudaに移動します。
ベンチマークをコンパイルします:
sh compile.sh
sh run-analysis.sh
各ベンチマークの分析はlog_<filename>という名前のログファイルのそれぞれのフォルダーに生成されます。
./summarize-results.sh
Nvidiaは、さまざまなアプリケーションに使用できるCUDAサンプルのセットを提供します。スイートを分析して、サンプル内のブロックサイズの独立したカーネルを識別しました。結果を再現するために、ステップは次のとおりです。
NVIDIA_CUDA-8.0_Samples/common/drano.mkのHOME変数をルートGPU Dranoディレクトリに更新します。
OpenGL(いくつかのベンチマークをコンパイルするために必要)をインストールします。 ubuntuでは、次のコマンドを使用できます。
sudo apt-get install freeglut3-dev
ディレクトリNVIDIA_CUDA-8.0_Samplesに移動します
ベンチマークをコンパイルします:
sh compile.sh
sh run-analysis.sh
各ベンチマークの分析はlog_<filename>という名前のログファイルのそれぞれのフォルダーに生成されます。
./summarize-bsize-independence.sh