Volatile Qualifier:
只要它遵守内存栅栏函数(内存栅栏函数)和内存可视性语义的内存排序语义,编译器就可以自由优化对全局或共享内存的读写操作(例如,通过将全局读取缓存到寄存器或L1缓存中) 同步功能(同步功能)。
可以使用volatile关键字禁用这些优化:如果位于全局或共享内存中的变量被声明为volatile,则编译器假定其值可以随时由另一个线程修改或使用,因此对此变量的任何引用都会编译为 一个实际的存储器读或写指令。
指针:
在主机上执行的代码中取消引用全局或共享内存的指针,或者在设备上执行的代码中托管内存时会导致未定义的行为,通常出现分段错误和应用程序终止。
通过获取__device__
,__shared__
或__constant__
变量的地址获得的地址只能用于设备代码。 设备存储器中描述的通过cudaGetSymbolAddress()获得的__device__
或__constant__
变量的地址只能用于主机代码。
作为使用C ++语法规则的结果,void指针(例如,由malloc()返回的)不能分配给没有类型转换的非void指针。
Assignment Operator:__constant__
变量只能通过运行时函数(Device Memory)从主机代码分配; 他们不能从设备代码分配。__shared__
变量不能作为声明的一部分进行初始化。 不允许将值分配给内置变量中定义的任何内置变量。
Address Operator:
不允许使用内置变量中定义的任何内置变量的地址。
运行时间类型信息(RTTI):
主机代码支持以下RTTI相关功能,但不支持设备代码。
- typeid运算符
- std::type_info
- dynamic_cast运算符
异常处理:
异常处理仅在主机代码中受支持,但不支持在设备代码中。
标准库:
除非另有说明,否则标准库仅在主机代码中受支持,但不支持在设备代码中。
外部联系:
使用extern限定符声明的函数的某些设备代码中的调用仅当函数在与设备代码相同的编译单元中定义时才是允许的,即,使用可重定位设备代码和nvlink将单个文件或多个文件链接在一起。
编译器生成的函数:
编译器生成函数的执行空间说明符(__host__
,__device__
)是调用它的所有函数的执行空间说明符的并集(注意__global__
调用者将被视为此分析的__device__
调用者)。
例子:
class Base {
int x;
public:
__host__ __device__ Base(void) : x(10) {}
};
class Derived : public Base {
int y;
};
class Other : public Base {
int z;
};
__device__ void foo(void)
{
Derived D1;
Other D2;
}
__host__ void bar(void)
{
Other D3;
}
这里,编译器生成的构造函数“Derived :: Derived”将被视为__device__
函数,因为它只能从__device__
函数“foo”调用。 编译器生成的构造函数“Other :: Other”将被视为__host__
__device__
函数,因为它是从__device__
函数“foo”和__host__
函数“bar”中调用的。