运行时 API 应用程序中的 cuda 上下文创建和资源关联

2024-04-26

我想了解如何在 cuda 运行时 API 应用程序中创建 cuda 上下文并与内核关联?

我知道这是由驱动程序 API 在幕后完成的。但我想了解一下创作的时间线。

首先,我知道 cudaRegisterFatBinary 是第一个 cuda api 调用,它向运行时注册一个 fatbin 文件。接下来是一些cuda函数注册API,它们在驱动层中调用cuModuleLoad。但是,如果我的 Cuda 运行时 API 应用程序调用 cudaMalloc,如何向该函数提供与上下文关联的指针,我认为应该事先创建该上下文。如何获取已创建的上下文的句柄并将未来的运行时 API 调用与其关联?请揭开内部运作的神秘面纱。

引用 NVIDIA 的文档

CUDA 运行时 API 调用在 CUDA 驱动程序 API CUcontext 上运行, 绑定到当前主机线程。

如果不存在绑定到当前的 CUDA Driver API CUcontext 调用 CUDA Runtime API 时的线程,需要 CUcontext 那么 CUDA Runtime 将隐式创建一个新的 CUcontext 在执行调用之前。

如果 CUDA 运行时创建 CUcontext,则 CUcontext 将是 使用 CUDA Runtime API 指定的参数创建 函数 cudaSetDevice、cudaSetValidDevices、cudaSetDeviceFlags、 cudaGLSetGLDevice、cudaD3D9SetDirect3DDevice、 cudaD3D10SetDirect3DDevice 和 cudaD3D11SetDirect3DDevice。注意 如果这些函数在以下情况下将失败并显示 cudaErrorSetOnActiveProcess 当 CUcontext 绑定到当前主机线程时调用。

CUcontext 的生命周期由引用计数管理 机制。 CUcontext的引用计数最初设置为0, 并且通过 cuCtxAttach 递增并通过 cuCtxDetach 递减。

如果 CUcontext 是由 CUDA 运行时创建的,则 CUDA 运行时 将减少函数中该 CUcontext 的引用计数 cudaThread退出。如果 CUcontext 是由 CUDA 驱动程序 API 创建的(或 由 CUDA Runtime API 库的单独实例创建), 那么 CUDA 运行时将不会增加或减少引用 该 CUcontext 的计数。

所有 CUDA Runtime API 状态(例如,全局变量的地址和 值)与其底层 CUcontext 一起移动。特别是,如果一个 CUcontext 从一个线程移动到另一个线程(使用 cuCtxPopCurrent 和 cuCtxPushCurrent) 那么所有 CUDA Runtime API 状态都将移动到 那个线程也是如此。

但我不明白的是cuda运行时如何创建上下文?为此使用了哪些 API 调用? nvcc 编译器是否插入一些 API 调用来在编译时执行此操作,还是完全在运行时完成?如果前者为真,那么哪些运行时 API 用于此上下文管理?后者是真的,具体是如何完成的?

如果上下文与主机线程关联,我们如何访问该上下文?它是否自动与线程处理的所有变量和指针引用相关联?

最终模块加载是如何在上下文中完成的?


CUDA 运行时维护要加载的模块的全局列表,并在每次将使用 CUDA 运行时的 DLL 或 .so 加载到进程中时添加到该列表中。但在创建设备之前,模块实际上并未加载。

上下文创建和初始化是由 CUDA 运行时“延迟”完成的——每次调用像 cudaMemcpy() 这样的函数时,它都会检查 CUDA 是否已初始化,如果没有,它会创建一个上下文(在先前由 cudaSetDevice() 指定的设备,或者如果从未调用 cudaSetDevice() 则为默认设备)并加载所有模块。从那时起,上下文就与该 CPU 线程关联,直到它被 cudaSetDevice() 更改为止。

您可以使用驱动程序 API 中的上下文/线程管理函数(例如 cuCtxPopCurrent()/cuCtxPushCurrent())来使用来自不同线程的上下文。

您可以调用 cudaFree(0);强制进行这种惰性初始化。

我强烈建议在应用程序初始化时这样做,以避免竞争条件和未定义的行为。继续并尽早在您的应用程序中枚举并初始化设备;完成后,在 CUDA 4.0 中,您可以从任何 CPU 线程调用 cudaSetDevice(),它将选择由初始化代码创建的相应上下文。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

运行时 API 应用程序中的 cuda 上下文创建和资源关联 的相关文章

  • 优化三角矩阵计算的 CUDA 内核的执行

    我正在开发我的第一个 Cuda 应用程序 并且我的内核 吞吐量低于预期 这似乎是目前最大的瓶颈 内核的任务是计算一个 N N 大小的矩阵 DD 包含数据矩阵上所有元素之间的平方距离 数据矩阵 Y 的大小为 N D 以支持多维数据 并存储为行
  • 如何在 gitlab-ci docker 执行器中使用 cuda

    我们正在使用 gitlab 持续集成来构建和测试我们的项目 最近 其中一个项目添加了 CUDA 的要求以启用 GPU 加速 我不想改变我们的管道 docker 和 gitlab ci 对我们来说运行良好 所以我想以某种方式让 docker
  • 为什么GK110有192个核心和4个扭曲?

    我想感受一下开普勒的架构 但这对我来说没有意义 如果一个 warp 有 32 个线程 其中 4 个被调度 执行 则意味着 128 个核心正在使用 64 个核心处于空闲状态 白皮书中提到了独立指令 那么64核是为这些指令保留的吗 如果是这样
  • Golang调用CUDA库

    我正在尝试从 Go 代码中调用 CUDA 函数 我有以下三个文件 test h int test add void test cu global void add int a int b int c c a b int test add v
  • Cuda Bayer/CFA 去马赛克示例

    我编写了一个 CUDA4 Bayer 去马赛克例程 但它比在 16 核 GTS250 上运行的单线程 CPU 代码慢 块大小是 16 16 图像暗淡是 16 的倍数 但更改此值并不会改善它 我做了什么明显愚蠢的事情吗 calling rou
  • 寻找 CUDA 中的最大值

    我正在尝试在 CUDA 中编写代码来查找最大值 对于给定的一组数字 假设您有 20 个数字 并且内核在 2 个块 每块 5 个线程 上运行 现在假设 10 个线程同时比较前 10 个值 并且thread 2找到最大值 因此线程 2 正在更新
  • 为什么 gcc 和 NVCC (g++) 会看到两种不同的结构大小?

    我正在尝试将 CUDA 添加到 90 年代末编写的现有单线程 C 程序中 为此 我需要混合两种语言 C 和 C nvcc 是 c 编译器 问题在于 C 编译器将结构视为特定大小 而 C 编译器将相同的结构视为略有不同的大小 那很糟 我对此感
  • “计算能力”是什么意思? CUDA?

    我是CUDA编程新手 对此了解不多 您能告诉我 CUDA 计算能力 是什么意思吗 当我在大学服务器上使用以下代码时 它向我显示了以下结果 for device 0 device lt deviceCount device cudaDevic
  • 同时使用 2 个 GPU 调用 cudaMalloc 时性能较差

    我有一个应用程序 可以在用户系统上的 GPU 之间分配处理负载 基本上 每个 GPU 都有一个 CPU 线程来启动一个GPU处理间隔当由主应用程序线程定期触发时 考虑以下图像 使用 NVIDIA 的 CUDA 分析器工具生成 作为示例GPU
  • CUDA素数生成

    当数据大小增加超过 260k 时 我的 CUDA 程序停止工作 它不打印任何内容 有人能告诉我为什么会发生这种情况吗 这是我的第一个 CUDA 程序 如果我想要更大的素数 如何在 CUDA 上使用大于 long long int 的数据类型
  • cuda 共享内存 - 结果不一致

    我正在尝试并行缩减以对 CUDA 中的数组求和 目前我传递一个数组来存储每个块中元素的总和 这是我的代码 include
  • 如何确定完整的 CUDA 版本 + 颠覆版本?

    Linux 上的 CUDA 发行版曾经有一个名为version txt例如 CUDA Version 10 2 89 这非常有用 但是 从 CUDA 11 1 开始 该文件不再存在 我如何在 Linux 上通过命令行确定并检查 path t
  • CUDA Visual Studio 2010 Express 构建错误

    我正在尝试在 64 位 Windows 7 上使用 Visual Studio 2010 Express 在 Windows 上开始 CUDA 编程 我花了一段时间来设置环境 然后我刚刚编写了我的第一个程序 helloWorld cu 目前
  • Nvcc 的版本与 CUDA 不同

    我安装了 cuda 7 但是当我点击 nvcc version 时 它打印出 6 5 我想在 GTX 960 卡上安装 Theano 库 但它需要 nvcc 7 0 我尝试重新安装cuda 但它没有更新nvcc 当我运行 apt get i
  • __syncthreads() 死锁

    如果只有部分线程执行 syncthreads 会导致死锁吗 我有一个这样的内核 global void Kernel int N int a if threadIdx x
  • 尝试构建我的 CUDA 程序时出现错误 MSB4062

    当我尝试构建我的第一个 GPU 程序时 出现以下错误 有什么建议可能会出什么问题吗 错误 1 错误 MSB4062 Nvda Build CudaTasks SanitizePaths 任务 无法从程序集 C Program 加载 文件 M
  • 在 cudaFree() 之前需要 cudaDeviceSynchronize() 吗?

    CUDA 版本 10 1 帕斯卡 GPU 所有命令都发送到默认流 void ptr cudaMalloc ptr launch kernel lt lt lt gt gt gt ptr cudaDeviceSynchronize Is th
  • 从 CUDA 设备写入输出文件

    我是 CUDA 编程的新手 正在将 C 代码重写为并行 CUDA 新代码 有没有一种方法可以直接从设备写入输出数据文件 而无需将数组从设备复制到主机 我假设如果cuPrintf存在 一定有地方可以写一个cuFprintf 抱歉 如果答案已经
  • CUDA - 将 CPU 变量传输到 GPU __constant__ 变量

    与 CUDA 的任何事情一样 最基本的事情有时也是最难的 所以 我只想将变量从 CPU 复制到 GPUconstant变量 我很难过 这就是我所拥有的 constant int contadorlinhasx d int main int
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I

随机推荐