1.1 编写第一个Cuda程序
Cuda 程序编写的关键在于核函数 (kernel) 的编写和调用。
核函数的编写要加上 __global__ 或者 __device__ 标识符 (两个下划线_)。
调用时要在函数名后加上 <<<grid_size, block_size>>>。
例如:
#include <stdio.h>
__global__ void hello_from_gpu()
{
printf("Hello World from the GPU!\n");
}
int main(void)
{
hello_from_gpu<<<1, 1>>>();
cudaDeviceSynchronize();
return 0;
}
关键在于核函数的标识符和其调用时需要加上<<<...>>>的形式。
1.2 用nvcc进行编译
可以使用nvcc对cuda编程的代码进行编译。
/usr/local/cuda/bin/nvcc -arch=compute_72 -code=sm_72 hello_cuda.cu -o hello_cuda -run
1.3 使用makefile进行编译
编译简单的cuda文件可以使用1.2的方法直接编译。对于复杂的工程文件可以编写Makefile文件进行编译,但编译规则需要设为nvcc。
1.4 用nvprof查看程序性能
/usr/local/cuda/bin/nvprof ./xxx
/usr/local/cuda/bin/nvprof --print-api-trace ./xxx
此外还可以使用
nvvp -vm /usr/bin/java
来可视化性能数据。
课后作业:
1. 利用Makefile规则,尝试编写批量编译工具,比如:同时编译5个cuda程序。
# Compiler and linker
CC = nvcc
# Object files
OBJS = program1.o program2.o program3.o program4.o program5.o
# Target executable
EXE = run_programs
# Compile flags
CFLAGS = -std=c++11
# Default target
all: $(EXE)
# Link objects to executable
$(EXE): $(OBJS)
$(CC) $(LFLAGS) $(OBJS) -o $(EXE)
# Compile CUDA programs
%.o: %.cu
$(CC) $(CFLAGS) -c $<
# Clean target
clean:
rm -f $(OBJS) $(EXE)
2. 利用Makefile规则,尝试加入链接库,比如:加入cuBLAS库编译cuda程序。
# Compiler and linker
CC = nvcc
# Object files
OBJS = main.o
# Target executable
EXE = run_cublas
# Compile flags
CFLAGS = -std=c++11
# Link flags
LFLAGS = -lcublas
# Default target
all: $(EXE)
# Link objects to executable
$(EXE): $(OBJS)
$(CC) $(LFLAGS) $(OBJS) -o $(EXE)
# Compile CUDA programs
%.o: %.cu
$(CC) $(CFLAGS) -c $<
# Clean target
clean:
rm -f $(OBJS) $(EXE)
3. 阅读Cuda sample code,尝试编写程序得到当前GPU的属性参数等。
#include <iostream>
#include <cuda_runtime.h>
int main() {
int deviceCount;
cudaGetDeviceCount(&deviceCount);
for (int i = 0; i < deviceCount; i++) {
cudaDeviceProp deviceProp;
cudaGetDeviceProperties(&deviceProp, i);
std::cout << "Device ID: " << i << std::endl;
std::cout << "Device Name: " << deviceProp.name << std::endl;
std::cout << "Device Total Global Memory: " << deviceProp.totalGlobalMem << " bytes" << std::endl;
std::cout << "Device Clock Rate: " << deviceProp.clockRate << " kHz" << std::endl;
std::cout << "Device Multiprocessor Count: " << deviceProp.multiProcessorCount << std::endl;
std::cout << std::endl;
}
return 0;
}