MIKE MURPHY, COMPILER DEVELOPMENT
作者信息未提供
链接时优化 (LTO) 旨在解决单独编译带来的优化限制,从而提高程序的运行时性能。
LTO 将单独编译的灵活性与全程序优化的性能相结合。
whole.cu 文件,通过 nvcc 编译优化,生成完全优化的可执行文件 a.Out。a.cu 和 b.cu 分别通过 nvcc -dc 编译优化生成 a.o 和 b.o(在各自范围内优化),然后链接生成 a.out(部分优化可执行文件)。a.cu 和 b.cu 分别通过 nvcc -dc -dlto 编译生成 a.o 和 b.o(LTO 中间表示),然后 nvlink -dlto 将其合并为 nvlink 中的中间表示,进行优化,最终生成完全优化的可执行文件 a.out。只需在 nvcc 命令行中添加 -dlto,例如:
nvcc -arch=sm_80 -dc *.cu -dltonvcc -arch=sm_80 *.o -dlto如果使用 -gencode 并希望在编译时保存多个中间文件,可以使用 code=lto_NN 作为目标,例如:
nvcc -gencode arch=compute_80,code=sm_80 -gencode arch=compute_60,code=lto_60 -dc *.cuLTO 在 CUDA 11.2 中引入;NVIDIA 是首家将 LTO 应用于 GPU 编译的公司。
可以对部分文件使用 LTO 构建,而对其他文件不使用。
a.cu 和 b.cu 通过 -dc -dlto 生成 LTO 中间表示 (a.o, b.o)。libc.a 包含非 LTO 设备代码。nvlink -dlto 对 a+b 执行 LTO,然后与 libc 链接,生成可执行文件。劳伦斯利弗莫尔国家实验室 (LLNL) 在一个大型蒙特卡洛风格应用程序上使用了 LTO,该程序包含数百个文件和大约 300,000 行代码。
https://www.osti.gov/biblio/1798430-enhancements-supporting-ic-usage-pem-libraries-next-gen-platformsnvcc 离线进行,也可以通过 nvrtc 在运行时进行。nvcc -dc -arch=lto_70 *.cu -fatbin 命令生成 LTO IR。它包含为多种架构生成的代码。nvrtc API,通过 nvrtcCompileProgram、nvrtcGetNVM、cuLinkCreate 等调用生成 LTO IR。nvrtc 生成 LTOIR (C++ 字符串):nvrtcProgram prog;
nvrtcCreateProgram(&prog, input, name, 0, nullptr, nullptr);
const char *options[2] = {"-dlto", "-dc"};
nvrtcResult result = nvrtcCompileProgram(prog, 2, options);
size_t irSize;
nvrtcGetNVMSize(prog, &irSize);
char *ltoIR = (char*)malloc(irSize);
nvrtcGetNVM(prog, ltoIR); // returns LTO IR
cuLink 驱动 API,链接在运行时执行:CUlinkState linkState;
CUjit_option jitoptions[] = {CU_JIT_OPTION_JIT_INPUT_TYPE};
void *jitoptionValues[] = {(void*)1};
cuLinkCreate(1, jitoptions, jitoptionValues, &linkState);
cuLinkAddData(linkState, CU_JIT_INPUT_NVVM,
ltoIR, irSize, name, 0, NULL, NULL);
cuLinkAddData( /* other input */ );
size_t size;
void *linkedCubin;
cuLinkComplete(linkState, &linkedCubin, &size);
cuModuleLoadData(&mod, linkedCubin);
CreatePlan API 中隐藏了 cuLink 的细节。数学库目前包含数千种手写内核的排列,但不能涵盖所有尺寸。通过将构建块与 JIT LTO 结合,我们可以生成用户所需的任何配置,同时获得最佳性能和最小库大小。
现状:
使用 JIT LTO:
- 单一用户配置: 统一的用户配置。
- 加载、存储、计算: 操作转换为 LTO-IR(链接时间优化中间表示)。
- JIT LTO: 在运行时(Runtime)通过 JIT LTO 处理 LTO-IR。
- SASS: 最终生成单一的 SASS 二进制文件。
- 优势: 更好的性能(Better performance),更小的二进制文件占用空间(Smaller binary footprint)。
示例: LAWA 应用程序约有 38K 行代码,分布在 300 多个文件中。
使用场景: 在应用程序需要反复运行时使用,而不是在迭代开发时使用。
使用 JIT LTO,较慢的链接时间可能通过参数化函数范围的缩小来抵消。
cuLinkCreate 选项:CU_JIT_REFERENCED_KERNEL_NAMESCU_JIT_REFERENCED_VARIABLE_NAMESCU_JIT_OPTIMIZE_UNUSED_DEVICE_VARIABLES欲了解更多信息,请参考以下链接:
博客:
手册:
* https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#optimization-of-separate-compilation -- nvcc
* https://docs.nvidia.com/cuda/cuda/nvrtc/index.html -- nvrtc
* https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__MODULE.html#group__CUDA__MODULE -- cuLink APIs
* https://docs.nvidia.com/cuda/deploy/cuda-compatibility/ -- 兼容性保证
用例:
* https://www.nvidia.com/en-us/on-demand/session/gtcfail21-a31155?playlistId=playlist-ead11304-9931-4e91-9d5a-fb0e1ef27014 -- “JIT LTO Adoption in cuSPARSE/cuFFT: Use Case Overview” in GTC Fall 2021.
* https://www.osti.gov/biblio/1798430-enhancements-supporting-ic-usage-pem-libraries-next-gen-platforms -- 提及使用 LTO 的 LLNL 论文。