reflection - 一个正在运行的 CUDA 内核的名字可以通过它的线程来获取吗?
问题描述
假设某个内核(一个__global__
名为 的函数foo
)正在 CUDA 设备上运行。并假设内核调用了一个有时从其他内核调用的__device__
函数bar
,即代码bar
在编译时不知道内核是否是foo
其他内核。
foo
运行的线程是否可以bar
获取名称“foo”、签名或内核的其他标识符,最好是人类可读的标识符?
如有必要,假设代码已使用--debug
,--device-debug
和/或中的任何一个进行编译--lineinfo
。
解决方案
内核可以读取特殊寄存器%gridid。%gridid 每次启动都是唯一的。如果性能好,那么一个简单的内核 prolog 可以让每个内核启动的一个线程使用func和 %gridid 输出 gridid 全局函数映射。或者,可以使用 CUPTI SDK Activity API 来收集这些信息。CUpti_ActivityKernel2 事件包含每次启动的元数据,包括 gridId 和 CUfunction 名称。
这是一个读取 %gridid 的示例。
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdint.h>
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);
static __device__ __inline__ uint64_t __gridid()
{
uint64_t gridid;
asm volatile("mov.u64 %0, %%gridid;" : "=l"(gridid));
return gridid;
}
__device__ void devPrintName()
{
static const char* name = __func__;
printf("%llu %s\n", __gridid(), name);
}
__global__ void globPrintName()
{
static const char* name = __func__;
printf("%llu %s\n", __gridid(), name);
devPrintName();
}
int main()
{
for (int i = 0; i < 4; ++i)
{
globPrintName<<<1,1,0>>>();
cudaDeviceReset();
}
return 0;
}
此示例输出
1 globPrintName
1 devPrintName
2 globPrintName
2 devPrintName
3 globPrintName
3 devPrintName
4 globPrintName
4 devPrintName
推荐阅读
- vim - 从vim中的书签目录模糊设置工作目录
- sql - 为什么 PATINDEX 不返回前导零以从 sql 中的字符串中提取数字?
- java - 低耦合理论与现实
- python - 在 Django 中哪里构建数据库对象(不使用 shell)?
- javascript - HTML/JS:暂停垂直滚动并为元素设置动画
- javascript - 将 Nest.js 应用程序导入为简单的 Express 中间件
- sql - 在 oracle sql 中运行列值的串联
- python - Numpy 2d 数组:在修改相邻元素时考虑边框元素
- r - 循环 colnames 基于向量模式
- python - 波浪号 (~) 运算符将布尔值更改为 int:Python 3