目录
1. 计时
1.1 linux
1.2 window下
2. nvprof实用工具
3. 设备管理cudaDeviceProp
4. 选择最佳gpu
5. 使用nvidia-smi查询GPU信息
5.1 nvidia-smi
5.2 nvidia-smi -L
5.3 nvidia-smi -q -i 0
5.4 nvidia-smi -q -i 0 -d MEMORY
5.5 nvidia-smi -q -i 0 -d UTILIZATION
5.6 其他-d命令
1. 计时
1.1 linux
#include <sys/time.h>
double cpuSecond() {
struct timeval tp;
gettimeofday(&tp, NULL);
return ((double)tp.tv_sec + (double)tp.tv_usec*1e-6);
}
// 调用
double start = cpuSecond();
kernel_name << <grid, block >> > (argument list);
cudaDeviceSynchronize(); // 显示的使其同步。
double cost = cpuSecond() - start;
1.2 window下
#include <time.h>
// 1 调用 clock_t
time_t begin = clock();
kernel_name << <grid, block >> > (argument list);
printf("\ngpu: %f s\n", (double)(clock() - begin) / CLOCKS_PER_SEC);
// 2 调用 time_t
time_t begin, end;
time(&begin);
kernel_name << <grid, block >> > (argument list);
time(&end);
time_t elapsed = end - begin;
printf("Time measured: %ld seconds.\n", elapsed);
2. nvprof实用工具
nvprof是命令行分析工具,功能很多,可以帮助从应用程序的CPU和GPU活动情况中获取时间线信息,其包括内核执行、内存传输以及CUDA API的调用。具体可通过以下命令查看。
nvprof --help
(1)上面命令如果报错:由于找不到cupti64_2022.2.1.dll,无法继续执行代码。。。
原因:nvprof工具属于插件,其dll在目录:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\extras\CUPTI\lib64
系统环境没有该目录,所以索引不到dll库。
解决办法:由于C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\bin在系统环境中,可以将cupti64_2022.2.1.dll拷贝到bin目录中.
(2)问题二,如果运行编译文件报错:Cannot find compiler ‘cl.exe‘ in PATH
nvcc kernel.cu -o kernel // 编译
则将C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin 加到系统路径中。
使用办法示例:
nvprof ./kernel
(1)可以看到哪些操作,被操作了多少次,平均、最大、最小用时是多少,用时占比是多少;
(2)cudaMalloc用时最多,被运行了3次,最小用时2us,最大用时259ms,平均用时86ms;
3. 设备管理cudaDeviceProp
CUDA Runtime API :: CUDA Toolkit Documentation
CUDA——通过cudaDeviceProp结构体查看GPU设备信息_Irving.Gao的博客-CSDN博客
struct cudaDeviceProp {
char name[256]; // 识别设备的ASCII字符串(比如,"GeForce GTX 940M")
size_t totalGlobalMem; // 全局内存大小(字节) byte/1024 -> kb/1024 -> m/1024 ->g
size_t sharedMemPerBlock; // 每个block内共享内存的大小
int regsPerBlock; // 每个block 32位寄存器的个数
int warpSize; // warp大小
size_t memPitch; // 内存中允许的最大间距字节数
int maxThreadsPerBlock; // 每个Block中最大的线程数是多少
int maxThreadsDim[3]; // 一个块中每个维度的最大线程数
int maxGridSize[3]; // 一个网格的每个维度的块数量
size_t totalConstMem; // 可用恒定内存量
int major; // 该设备计算能力的主要修订版号
int minor; // 设备计算能力的小修订版本号
int clockRate; // 时钟速率
size_t textureAlignment; // 该设备对纹理对齐的要求
int deviceOverlap; // 一个布尔值,表示该装置是否能够同时进行cudamemcpy()和内核执行
int multiProcessorCount; // 设备上的处理器的数量
int kernelExecTimeoutEnabled; // 一个布尔值,该值表示在该设备上执行的内核是否有运行时的限制
int integrated; // 返回一个布尔值,表示设备是否是一个集成的GPU(即部分的芯片组、没有独立显卡等)
int canMapHostMemory; // 表示设备是否可以映射到CUDA设备主机内存地址空间的布尔值
int computeMode; // 一个值,该值表示该设备的计算模式:默认值,专有的,或禁止的
int maxTexture1D; // 一维纹理内存最大值
int maxTexture2D[2]; // 二维纹理内存最大值
int maxTexture3D[3]; // 三维纹理内存最大值
int maxTexture2DArray[3]; // 二维纹理阵列支持的最大尺寸
int concurrentKernels; // 一个布尔值,该值表示该设备是否支持在同一上下文中同时执行多个内核
}
常用功能示例:
#include <cuda_runtime.h>
#include <stdio.h>
#include <iostream>
#include "device_launch_parameters.h"
#define CHECK(call) \
{ \
const cudaError_t error_code = call; \
if (error_code != cudaSuccess) \
{ \
printf("CUDA Error:\n"); \
printf(" File: %s\n", __FILE__); \
printf(" Line: %d\n", __LINE__); \
printf(" Error code: %d\n", error_code); \
printf(" Error text: %s\n", \
cudaGetErrorString(error_code)); \
exit(1); \
} \
}
int main(int argc, char** argv)
{
int dev = 0;
cudaDeviceProp devProp;
CHECK(cudaGetDeviceProperties(&devProp, dev));
std::cout << "使用GPU device " << dev << ": " << devProp.name << std::endl;
// 流式多处理器:一个sm可以处理多个block,一个block只能被一个sm处理,且sm处理的基本单元是线程束warps.
std::cout << "SM的数量:" << devProp.multiProcessorCount << std::endl;
std::cout << "每个线程块的共享内存大小:" << devProp.sharedMemPerBlock / 1024.0 << " KB" << std::endl;
std::cout << "每个线程块的最大线程数:" << devProp.maxThreadsPerBlock << std::endl;
std::cout << "每个SM的最大线程数:" << devProp.maxThreadsPerMultiProcessor << std::endl;
std::cout << "每个SM的最大线程束数:" << devProp.maxThreadsPerMultiProcessor / 32 << std::endl;
return EXIT_SUCCESS;
}
每个SM的最大线程束数是32,而一个线程束是32个线程,则每个SM最大有32x32=1024个线程也就是maxThreadsPerMultiProcessor,有14个SM,所以最大处理32x32x14=14336个线程。
更多功能示例:
#include "cuda_runtime.h"
#include "device_launch_parameters.h" // threadIdx
#include <stdio.h> // io
#include <time.h> // time_t clock_t
#include <stdlib.h> // rand
#include <memory.h> //memset
#include <math.h>
#define CHECK(call) \
{ \
const cudaError_t error_code = call; \
if (error_code != cudaSuccess) \
{ \
printf("CUDA Error:\n"); \
printf(" File: %s\n", __FILE__); \
printf(" Line: %d\n", __LINE__); \
printf(" Error code: %d\n", error_code); \
printf(" Error text: %s\n", \
cudaGetErrorString(error_code)); \
exit(1); \
} \
}
int main(void)
{
// 1 检查有多少个gpu
int deviceCount = 0;
cudaGetDeviceCount(&deviceCount);
if (deviceCount == 0)
{
printf("There are no available device(s) that support CUDA\n");
}
else
{
printf("Detected %d CUDA Capable device(s)\n", deviceCount);
}
// 2 设置使用哪个显卡,卡号0的显卡名称。
int dev = 0;
CHECK(cudaSetDevice(dev)); // 设置使用哪个显卡
cudaDeviceProp deviceProp;
CHECK(cudaGetDeviceProperties(&deviceProp, dev));
printf("Device %d: \"%s\"\n", dev, deviceProp.name); // 卡号0的显卡名称。
// 3 驱动等版本, 显卡驱动最高支持的cuda版本和当前运行的cuda版本。
int driverVersion = 0, runtimeVersion = 0;
cudaDriverGetVersion(&driverVersion);
cudaRuntimeGetVersion(&runtimeVersion);
printf(" CUDA Driver Version / Runtime Version %d.%d / %d.%d\n",
driverVersion / 1000, (driverVersion % 100) / 10, // 显卡驱动最高支持的cuda版本
runtimeVersion / 1000, (runtimeVersion % 100) / 10); // 当前运行的cuda版本
// 4 cuda计算能力. 7.5. 8.5之类的
printf(" CUDA Capability Major/Minor version number: %d.%d\n",
deviceProp.major, deviceProp.minor);
// 5 GPU Clock rate: 1575 MHz (1.58 GHz)
printf(" GPU Clock rate: %.0f MHz (%0.2f "
"GHz)\n", deviceProp.clockRate * 1e-3f,
deviceProp.clockRate * 1e-6f);
// 6 Max Texture Dimension Size (x,y,z) 1D=(131072), 2D=(131072,65536), 3D=(16384,16384,16384)
printf(" Max Texture Dimension Size (x,y,z) 1D=(%d), "
"2D=(%d,%d), 3D=(%d,%d,%d)\n", deviceProp.maxTexture1D,
deviceProp.maxTexture2D[0], deviceProp.maxTexture2D[1],
deviceProp.maxTexture3D[0], deviceProp.maxTexture3D[1],
deviceProp.maxTexture3D[2]);
// 7 Max Layered Texture Size (dim) x layers 1D=(32768) x 2048, 2D=(32768,32768) x 2048
printf(" Max Layered Texture Size (dim) x layers 1D=(%d) x %d, "
"2D=(%d,%d) x %d\n", deviceProp.maxTexture1DLayered[0],
deviceProp.maxTexture1DLayered[1], deviceProp.maxTexture2DLayered[0],
deviceProp.maxTexture2DLayered[1],
deviceProp.maxTexture2DLayered[2]);
/*
Total amount of constant memory: 65536 bytes
Total amount of shared memory per block: 49152 bytes
Total number of registers available per block: 65536
Warp size: 32
Maximum number of threads per multiprocessor: 1024
Maximum number of threads per block: 1024
Maximum sizes of each dimension of a block: 1024 x 1024 x 64
Maximum sizes of each dimension of a grid: 2147483647 x 65535 x 65535
Maximum memory pitch: 2147483647 bytes
*/
printf(" Total amount of constant memory: %lu bytes\n",
deviceProp.totalConstMem);
printf(" Total amount of shared memory per block: %lu bytes\n",
deviceProp.sharedMemPerBlock);
printf(" Total number of registers available per block: %d\n",
deviceProp.regsPerBlock);
printf(" Warp size: %d\n",
deviceProp.warpSize);
printf(" Maximum number of threads per multiprocessor: %d\n",
deviceProp.maxThreadsPerMultiProcessor);
printf(" Maximum number of threads per block: %d\n",
deviceProp.maxThreadsPerBlock);
printf(" Maximum sizes of each dimension of a block: %d x %d x %d\n",
deviceProp.maxThreadsDim[0],
deviceProp.maxThreadsDim[1],
deviceProp.maxThreadsDim[2]);
printf(" Maximum sizes of each dimension of a grid: %d x %d x %d\n",
deviceProp.maxGridSize[0],
deviceProp.maxGridSize[1],
deviceProp.maxGridSize[2]);
printf(" Maximum memory pitch: %lu bytes\n",
deviceProp.memPitch);
}
4. 选择最佳gpu
#include "cuda_runtime.h"
#include "device_launch_parameters.h" // threadIdx
int main(void)
{
// 计算有多少个gpu
int numDevices = 0;
cudaGetDeviceCount(&numDevices);
// 选择最佳gpu: 比较GPU包含的多处理器的数量选出计算能力最佳的GPU
if (numDevices > 1)
{
int maxMultiprocessors = 0, maxDevice = 0; // 多处理器的数量
for (int device = 0; device < numDevices; device++)
{
cudaDeviceProp props;
cudaGetDeviceProperties(&props, device);
if (props.multiProcessorCount > maxMultiprocessors)
{
maxMultiprocessors = props.multiProcessorCount;
maxDevice = device;
}
}
cudaSetDevice(maxDevice); // 将使用的gpu设置成处理器最多的那个gpu
}
}
5. 使用nvidia-smi查询GPU信息
5.1 nvidia-smi
5.2 nvidia-smi -L
GPU以及每个GPU的设备ID
5.3 nvidia-smi -q -i 0
0号gpu详细信息,非常信息,这里只是截图部分。
5.4 nvidia-smi -q -i 0 -d MEMORY
只是显示内存信息
5.5 nvidia-smi -q -i 0 -d UTILIZATION
设备使用情况
5.6 其他-d命令
nvidia-smi -q -i 0 -d 再加上后面这些字符串,即可获取相应的信息。
·MEMORY
·UTILIZATION
·ECC
·TEMPERATURE
·POWER
·CLOCK
·COMPUTE
·PIDS
·PERFORMANCE
·SUPPORTED_CLOCKS
·PAGE_RETIREMENT
·ACCOUNTING文章来源:https://www.toymoban.com/news/detail-620942.html
待续。。。文章来源地址https://www.toymoban.com/news/detail-620942.html
到了这里,关于《cuda c编程权威指南》03 - cuda小功能汇总的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!