cudaMemcpy无效参数。

6
我的程序运行了两个线程——线程A(用于输入)和线程B(用于处理)。我还有一对指针指向两个缓冲区,这样当线程A完成将数据复制到缓冲区1时,线程B开始处理缓冲区1,线程A开始将数据复制到缓冲区2。然后当缓冲区2满时,线程A将数据复制到缓冲区1,线程B处理缓冲区2,以此类推。
我的问题出现在尝试将Buffer[] cudaMemcpy到d_Buffer中时(之前由主线程cudaMalloc'd,即在线程创建之前。Buffer[]也是由主线程malloc'd)。我得到一个“无效参数”错误,但不知道哪个是无效参数。
我将程序简化为单线程程序,但仍然使用两个缓冲区。也就是说,复制和处理是依次进行的,而不是同时进行的。cudaMemcpy行与双线程行完全相同。单线程程序可以正常工作。
我不确定错误出在哪里。
谢谢。
问候, Rayne
1个回答

5
如果您使用的是CUDA 3.2或更早版本,则原因在于GPU上下文与特定线程绑定。如果多线程程序从不同主机线程上分配内存到同一GPU上,则分配将建立不同的上下文,而来自一个上下文的指针在另一个上下文中是不可移植的。每个上下文都有自己的“虚拟”内存空间来处理。

解决方案是使用上下文迁移API将单个上下文从一个线程转移到另一个线程,以便它们可以工作,或者尝试新的公共CUDA 4.0rc2发布版,它应该支持您正在尝试做的事情,而无需使用上下文迁移。缺点是4.0rc2是一个测试版本,并且需要特定的Beta发布驱动程序。该驱动程序可能无法适用于所有硬件(例如笔记本电脑)。

谢谢!我找到了cuCtxPushCurrent和cuCtxPopCurrent,它们是驱动程序API。是否有用于上下文迁移的运行时API?我可以在同一个程序中混合使用运行时和驱动程序API吗? - Rayne
由于上下文在运行时API中是隐式/抽象的,因此没有运行时API上下文管理例程。但是,自CUDA 3.1发布以来,您可以安全地混合运行时和驱动程序API调用。您可能会发现最容易使用驱动程序API创建上下文并将其从线程迁移到线程,然后在上下文中使用运行时API进行其余操作。请注意,上下文迁移本身不是免费的,它确实增加了一些延迟,但这是在CUDA 4.0之前实现您想要的官方方式。 - talonmies
我想尝试一下CUDA 4.0。我是否只需在当前安装的CUDA 3.2上安装CUDA 4.0?我需要删除任何东西吗,例如驱动程序等? - Rayne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接