执行环境和内存模型:
执行环境:
CUDA执行模型基于线程,线程块和网格的原语,内核函数定义由线程块和网格中的各个线程执行的程序。 当调用内核函数时,网格的属性由执行配置来描述,该配置在CUDA中具有特殊的语法。 对CUDA中的动态并行性的支持扩展了在新网格上配置,启动和同步设备上运行的线程的能力。
父子网格:
配置和启动新网格的设备线程属于父网格,并且由调用创建的网格是子网格。
子网格的调用和完成是正确嵌套的,这意味着直到由其线程创建的所有子网格完成之后,才认为父网格完整。 即使调用线程没有在启动的子网格上显式同步,运行时也会保证父级和子级之间的隐式同步。
CUDA原语的范围:
在主机和设备上,CUDA运行时提供了一个API用于启动内核,等待启动的工作完成以及跟踪通过流和事件启动的依赖关系。 在主机系统上,启动状态和引用流和事件的CUDA原语被进程内的所有线程共享; 但是进程独立执行并且可能不共享CUDA对象。
设备上存在类似的层次结构:启动的内核和CUDA对象对于线程块中的所有线程均可见,但在线程块之间是独立的。 这意味着例如一个流可以由一个线程创建并由同一线程块中的任何其他线程使用,但不能与任何其他线程块中的线程共享。
同步:
来自任何线程的CUDA运行时操作(包括内核启动)在线程块中都可见。 这意味着父网格中的调用线程可以在该线程启动的网格,线程块中的其他线程或同一线程块内创建的流上执行同步。 只有在块中所有线程的所有启动都完成之后才执行线程块。 如果一个块中的所有线程在所有子启动完成之前退出,则会自动触发同步操作。
流和事件:
CUDA流和事件允许控制网格启动之间的依赖关系:启动到同一个流中的网格按顺序执行,事件可用于创建流之间的依赖关系。 在设备上创建的流和事件可以达到完全相同的目的。
在网格内创建的流和事件存在于线程块范围内,但在创建它们的线程块之外使用时具有未定义的行为。 如上所述,线程块启动的所有工作在块退出时隐含地同步; 这项工作包括发布到流中的工作,所有依赖关系都得到适当解决。 在线程块范围之外修改的流上的操作行为未定义。
当在任何内核中使用时,在主机上创建的流和事件都具有未定义的行为,就像由父网格创建的流和事件在子网格内使用时具有未定义的行为一样。