__global__ 是否比 __device__ 有开销?

Does __global__ have overhead over __device__?

This question__device____global__的区别。

区别是:

__device__ functions can be called only from the device, and it is executed only in the device.

__global__ functions can be called from the host, and it is executed in the device.

我将 __global____device__ 之间的区别解释为类似于 publicprivate class 访问说明符。重点是防止意外地从主机调用 __device__ 函数。听起来我可以在不改变程序行为的情况下将所有返回 void 的函数标记为 __global__。这会改变程序性能吗?

是的,与 __device__ 相比,__global__ 有开销,但还有其他细节需要注意。你提出的建议可能不是一个好主意。

__global__ 是设备代码 入口点,来自主机代码。最初,GPU 上没有代码 运行。当您的主机代码决定要在 GPU 上开始一些处理时,这 只能 通过调用 __global__ 函数(即 so-called 内核启动).

您可以从设备代码调用 __global__ 函数,但那是在调用一个名为 CUDA Dynamic Parallelism 的函数,它具有内核启动的所有属性。如果您是初学者,您几乎肯定不想这样做。

如果您在 GPU 上有代码 运行,并且您想在 CUDA 线程的上下文中调用一个函数,方法是调用一个 __device__ 函数。

It sounds like I could tag all void-returning functions as __global__ without changing program behavior. Would this change program performance?

它会改变行为和性能。

当您调用 __global__ 函数(无论是从主机代码还是设备代码)时,唯一的方法是通过正确配置的内核启动。使用 CUDA 运行时中的典型方法 API,即:

kernel<<<blocks, threads, ...>>>(... arguments ...);

triple-chevron 语法中的那些东西使它不同于普通的函数调用,并且它的行为也会不同。它将启动一个新内核,它有自己的网格(与内核启动相关的 threads/blocks 的补充)。

当你调用一个__device__函数时,它看起来像一个普通的函数调用:

func(... arguments ...);

并且行为也像一个。它在单线程上下文中运行,不会启动任何新的 threads/blocks/内核来为函数调用提供服务。

您可能想花几个小时 orderly introduction 讨论该主题。只是一个建议,随你便。