GPU Drano는 GPU 프로그램을위한 정적 분석 도구입니다. GPU Drano의 분석 중 하나는 CUDA 코드에서 코일이없는 메모리 액세스를 찾는 것입니다. GPU Drano가 지원하는 다른 분석은 GPU 프로그램의 블록 크기 독립성을 입증하는 분석입니다.
현대 GPUS 번들 스레드가 날실에 들어갑니다. 워프의 모든 스레드는 잠금 장치에서 작업을 수행합니다. 메모리가 인접하거나 메모리에 충분히 가까이 있으면 다른 메모리 위치에 대한 메모리 액세스를 단일로드/저장으로 합쳐질 수 있습니다. 워프에 의해 액세스 된 메모리가 멀리 떨어져 있으면 메모리 트랜잭션을 완료하기 위해 여러로드/스토어가 필요하며 액세스가 코반이되지 않는다고 합니다.
GPU 커널은 블록 크기 독립 이라고합니다. 총 스레드 수를 동일하게 유지하면서 블록 크기를 수정하면 프로그램의 기능이 중단되지 않습니다. 이는 GPU 프로그램에서 올바른 블록 크기 튜닝에 필수적이며, 이는 종종 프로그램 성능을 향상시키는 데 사용됩니다.
또한 코일이없는 액세스를 식별하기위한 동적 분석을 구현했습니다.이 저장소에서 사용할 수 있습니다.
GPU Drano는 Google의 오픈 소스 CUDA 구현 : gpucc 사용하여 LLVM의 컴파일러 패스로 구현됩니다. 따라서 Drano는 LLVM과 밀접하게 결합됩니다.
Drano는 LLVM 버전 6.0 이상이 필요합니다. 또한 Nvidia의 CUDA 툴킷 (버전 7.5 이상)이 필요합니다. Ubuntu 16.04 LTS에서 테스트되었지만 대부분의 기존 Linux 시스템에서 작동해야합니다.
정적 분석 자체에는 GPU가 필요하지 않습니다. 그러나 프로그램을 실행하고 동적 anlaysis를 실행하려면 NVIDIA GPU 및 호환 드라이버가 필요합니다. 자세한 내용은 Nvidia의 시스템 요구 사항을 확인하십시오.
알고리즘 및 설계 선택의 세부 사항은 다음 논문에서 찾을 수 있습니다.
프로젝트에 포함 된 스크립트 installnrun.sh 우분투 시스템에서 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
LLVM에 GPU Drano 추가 :
GPU Drano의 src/ 폴더를 소스 코드에서 디렉토리 llvm/lib/Transforms/UncoalescedAnalysis 에 복사하십시오.
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 드라이버, 툴킷 및 SDK를 구축하는 프로세스를 간략하게 설명합니다. 이 스크립트는 기존 NVIDIA 드라이버를 무시할 위험을 피하기 위해 댓글을 달았습니다. 정적 분석을 실행하려면 툴킷과 SDK 만 있으면됩니다. 또한 동적 분석 및 CUDA 프로그램 자체를 실행하려면 운전자와 작업 GPU가 필요합니다.
NVIDIA 드라이버, CUDA 툴킷 및 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 의 경로는 시스템에 따라 다를 수 있습니다.
LLVM은 build/lib/ 디렉토리 아래에서 LLVMUncoalescedAnalysis.so 라는 공유 객체 .so 파일을 생성해야합니다.
LLVM Complier clang CUDA 프로그램을 컴파일 할 때 별도의 장치 (GPU 커널 코드)와 호스트 (CPU에서 CODE) IR 파일을 생성합니다. GPU Drano는 장치 코드의 LLVM IR 파일을 분석합니다.
예를 들어, gaussian 벤치 마크의 Rodinia 커널 코드를 분석하겠습니다. 우리는 디렉토리를 rodinia_3.1/cuda/gaussian/ 로 변경합니다.
먼저 Clang이 관심있는 코드에 대해 LLVM IR 파일을 생성했습니다.
clang++ -S -g -emit-llvm gaussian.cu
생성 된 IR의 소스 코드 위치에 대한 디버그 정보를 유지하기 위해 디버그 기호 -g 로 컴파일하십시오. 이는 소스 코드 위치를 LLVM IR로부터 잠재적으로 비정상적으로 액세스 할 수있는 소스 코드 위치를 가리키는 데 사용됩니다.
컴파일은 두 개의 파일을 생성합니다.
gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll
gaussian.ll
그런 다음 GPU Drano Binary 로의 경로를 지정하고 패스 -interproc-uncoalesced-analysis 지정하여 LLVM의 opt 를 통해 정적 분석을 실행할 수 있습니다. 이 패스는 비정상적인 접근을 감지하기위한 간호 적 분석입니다. 그것은 콜 그라프에서 가장 큰 기능 분석으로 시작한 다음 토폴로지 순서로 칼리의 분석을 진행합니다. 특정 Callee를 분석하는 동안 모든 발신자의 통화 컨텍스트의 결합을 고려합니다. 모든 초기 함수 인수가 Thread의 ID와 무관 한 것으로 가정하는 요법 내 분석을 실행하려면 -interproc-uncoalesced-analysis Analysis 대신에 실행될 Pass -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의 출력으로 리디렉션하여 표준 오류로 기록되어 파일로 리디렉션 될 수 있습니다.
Verbose 분석 결과 (분석 정보로 주석이 달린 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
각 결과 항목은 소스 코드에서 잠재적으로 비정상적인 액세스를 가리 킵니다. 예를 들어, method Fan1() 의 Gaussian.cu에서 295 행에서 m_cuda 에 대한 액세스는 코일이되지 않습니다.
마찬가지로, 블록 크기 독립성 분석을위한 생성 된 결과는 블록 크기 독립된 모든 커널을 식별합니다!
Rodinia는 다른 도메인의 22 개 프로그램으로 구성된 GPU 프로그램의 인기있는 벤치 마크 제품군입니다. 우리는 스위트를 분석하고 정적 분석을 사용하여 111 개의 실제 비 동정 액세스를 발견했습니다. 결과를 재현하려면 다음과 관련된 단계는 다음과 같습니다.
rodinia_3.1/common/make.config 에서 Cuda 및 Drano 구성을 업데이트하십시오. NVIDIA 툴킷 및 SDK 경로로 CUDA_DIR 및 SDK_DIR 설정하십시오. GPU로가는 경로로 opt 별칭을 업데이트하십시오. DRANO BINARY LLVMUncoalescedAnalysis.so .
벤치 마크 디렉토리 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을 설치하십시오 (몇 가지 벤치 마크를 컴파일하는 데 필요). 우분투에서 다음 명령을 사용할 수 있습니다.
sudo apt-get install freeglut3-dev
디렉토리 NVIDIA_CUDA-8.0_Samples 로 이동하십시오
벤치 마크 컴파일 :
sh compile.sh
sh run-analysis.sh
각 벤치 마크를 분석하면 log_<filename> 이라는 로그 파일의 각 폴더가 생성됩니다.
./summarize-bsize-independence.sh