Ele*_*ito 2 multithreading cuda unified-memory
我正在编写一个程序,该程序从摄像机检索图像并使用CUDA处理它们。为了获得最佳性能,我将CUDA统一内存缓冲区传递给图像获取库,该库在另一个线程中写入该缓冲区。
这会导致各种各样奇怪的结果,使程序无法在我无法访问的库代码中挂起。如果我使用普通的内存缓冲区,然后复制到CUDA,则此问题已解决。因此,我开始怀疑可能不允许从另一个线程进行写操作,并且像我一样用Google搜索时,找不到明确的答案。
那么是否允许从另一个CPU线程访问统一内存缓冲区?
从多个线程写入统一内存缓冲区应该没有问题。
但是,请记住所施加的限制,当concurrentManagedAccess
设备属性是不正确的。在这种情况下,当你有一个管理的缓冲区,你推出一个内核,没有任何形式的CPU /主机线程允许访问,该缓冲区,或任何其他托管缓冲区,直到你执行一个cudaDeviceSynchronize()
内核调用之后。
在多线程环境中,这可能需要花费一些明显的精力才能实施。
我想这也是您的帖子,类似于本次演奏会。请注意,TX2应该将此属性设置为false。
请注意,在非并发情况下,可以通过谨慎使用stream来修改此一般规则。但是,这些限制仍然适用于附加到已在其中启动内核的流的缓冲区(或未明确附加到任何流的缓冲区):当上述属性为false时,将无法通过任何CPU线程进行访问。
这种行为的动机大致如下。CUDA运行时不知道托管缓冲区之间的关系,无论这些缓冲区是在哪里创建的。在一个线程中创建的缓冲区可以很容易地在其中带有带有嵌入式指针的对象,没有什么可以防止或限制这些指针指向另一个托管缓冲区中的数据的。甚至是后来创建的缓冲区。甚至在另一个线程中创建的缓冲区。安全的假设是任何链接都是可能的,因此,在没有任何其他协商的情况下,当启动内核时,CUDA运行时中的托管内存子系统必须将所有托管缓冲区移至GPU。这使得所有CPU线程(任何线程,任何位置)都无法访问托管缓冲区。在正常的程序流程中,访问将在cudaDeviceSynchronize()调用的下一次出现时恢复。一旦发出调用的CPU线程完成了调用并继续进行,托管缓冲区将再次对(所有)CPU线程可见。另一个内核启动(任何地方)都会重复该过程,并中断可访问性。重复一遍,这是在concurrentManagedAccess
GPU上的属性不正确时有效的机制,可以通过上述流附加机制在某种程度上修改此行为。