GPU Drano是用于GPU程序的静态分析工具。 GPU Drano中的分析之一是在CUDA代码中查找不透明的内存访问。 GPU Drano支持的另一个分析是分析以证明GPU计划的块大小独立性。
现代GPU捆绑线将线程变成扭曲。经纱中的所有线程都以锁定操作执行操作。如果内存相邻或足够接近内存,则可以将内存访问到不同的内存位置。当经纱访问的内存距离很远时,需要多个负载/存储来完成内存事务,我们说访问是不循环的。
据说GPU内核是独立的,如果修改块大小,同时保持螺纹总数相同,则不会破坏程序的功能。这对于在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了在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 Source:
将当前的工作目录更改为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 :
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
这是cmake LLVM目录( ../llvm )的路径。 CMAKE为您的系统配置LLVM。它应该在您当前的工作目录( build/ )中生成几个文件。该命令make LLVM和Drano构建。
理想情况下,使用make -j N其中n是您需要并行构建的内核数,因为LLVM需要很长时间才能构建。
注意:LLVM构建需要大量内存来编译,特别是在链接步骤中。如果您的RAM <8 GB,LLVM可能无法构建。如果是这样,您可以在没有-j选项的情况下重新make 。这只会重新编译构建的失败部分,并且节省的时间比从一开始就使用-j时间要多。
安装LLVM和GPU DRANO PERCOR sudo make install 。这应该在默认位置(或指定位置)中安装库和二进制文件。如果在本地安装,则本指南假定Bash可以在其路径中找到命令。
以上是快速入门指南。如果您不熟悉LLVM,则可以在以下位置找到安装的所有详细信息:http://llvm.org/docs/gettingstarted.html
脚本installnrun.sh简要介绍了构建NVIDIA驱动程序,工具包和SDK的过程。该脚本已发表评论,以避免覆盖现有NVIDIA驱动程序的风险。请注意,我们只需要工具包和SDK来运行静态分析。我们还需要驱动程序和一个工作的GPU来执行动态分析和CUDA程序本身。
安装NVIDIA驱动程序,CUDA工具包和SDK:请参阅NVIDIA安装指南以获取说明。
总而言之,如果您使用最近和流行的Linux发行版,则应该能够使用自动下载工具来安装所需的驱动程序和SDK。
如果您已经安装了所需的驱动程序和SDK,则可以跳过此步骤。覆盖现有驱动程序可能不是一个好主意,因为这可能使您的系统无法使用。
您可能需要G ++-Multilib来安装clang要求的必要库。
此步骤是可选的。现在应该使用clang或clang++编译的简单CUDA程序,例如“ Hello World”:
clang -x cuda helloWorld.cu
-x cuda选项明确指出该语言。您也可以省略它,Clang将其作为CUDA程序推断。
注意:您的叮当声安装可能无法找到几个内部LLVM功能,如果是的,则可能需要包括-lcudart 。您可能还需要指向cudart.so的位置。
例子:
clang -x cuda -L /usr/local/cuda/targets/x86_64-linux/lib/ -lcudart helloWorld.cu
因此,您的cudart路径可能会有所不同,具体取决于您的系统。
LLVM应该生成一个共享对象.so文件,称为LLVMUncoalescedAnalysis.so ,在build/lib/ Directory下。
LLVM Crumplier clang在编译CUDA程序时生成单独的设备(GPU内核代码)和主机(在CPU上运行的代码)。 GPU Drano分析设备代码的LLVM IR文件。
例如,让我们分析为gaussian基准测试的Rodinia内核代码。我们将目录更改为rodinia_3.1/cuda/gaussian/ 。
首先,我们的clang生成了我们感兴趣的代码的LLVM IR文件:
clang++ -S -g -emit-llvm gaussian.cu
请注意,我们使用DEBUG SYMBER -g编译,以保留有关生成IR中源代码位置的调试信息。这用于指向LLVM IR的潜在不透明访问的源代码位置。
该汇编生成了两个文件:
gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll
gaussian.ll
然后,我们可以通过指定GPU Drano二进制的opt并指定Pass -interproc-uncoalesced-analysis以运行静态分析。该通行证是一种概论分析,可检测不循环的访问。它从对呼叫图中最高功能的分析开始,然后按照拓扑顺序进行对其callees的分析。在分析特定的Callee时,它考虑了所有呼叫者的呼叫上下文的联接。为了运行术中分析(假设所有初始函数参数与线程ID无关),请指定Pass- -uncoalesced-analysis进行运行,而不是-interproc-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从标准输入中读取红外文件。 opt将其自己无趣的输出写入标准输出,因此我们将其重定向到/dev/null gpu drano的输出被写入标准误差,可以重定向到文件。
为了生成详细分析结果(使用分析信息注释的LLVM IR), opt使用其他额外的-debug-only=uncoalesced-analysis Flag运行。
以下命令可用于在程序上运行块大小的独立性分析。
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 ,在方法Fan1()中Gaussian.cu中的第59列是不透明的。
同样,用于块大小独立性分析的生成的结果确定所有具有块大小独立的内核!
Rodinia是由GPU计划的流行基准套件,该计划由来自不同领域的22个程序组成。我们分析了该套件,并使用静态分析发现了111个真正的不透明访问。为了重现结果,以下是所涉及的步骤:
在rodinia_3.1/common/make.config中更新CUDA和DRANO配置。使用NVIDIA工具包和SDK路径设置CUDA_DIR和SDK_DIR 。更新opt ALIAS和GPU DRANO二进制LLVMUncoalescedAnalysis.so 。
转到Benchmarks目录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变量到root 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