严格别名、CUdeviceptr 和 cuMemAllocManaged
Strict aliasing, CUdeviceptr, and cuMemAllocManaged
cuMemAllocManaged
要求作为其第一个参数提供的指针是 CUdeviceptr *
类型(技术上 unsigned int *
),但使用托管内存的要点是能够操纵主机和设备上同一内存地址中的数据。因此,为了能够在主机上操作托管数据,那些 CUdeviceptr
s 必须在访问之前转换为适当的指针类型(例如 float *
或 double *
),或者主机必须存储正确类型的指针并转换为 CUdeviceptr
。据我所知,前者显然违反了严格的别名规则,但后者是否也违反了严格的别名规则,或者它是否仍然安全,因为严格的别名问题仅在通过类型双关指针显式访问数据时发生?
换句话说,即使启用了严格的别名,类似于以下代码段的模式是否安全?
float* turkey;
CUdeviceptr* goose = reinterpret_cast<CUdeviceptr*>(&turkey); // alternatively, (CUdeviceptr*)&turkey
// error checking code elided
cuMemAllocManaged(goose, sizeof(float)*10000, CU_MEM_ATTACH_GLOBAL);
// initialize turkey
// supply goose as an argument to a kernel function
cuCtxSynchronize();
// do stuff with turkey on host again
看起来这两种行为都没有问题。经过 http://www.cocoawithlove.com/2008/04/using-pointers-to-recast-in-c-is-bad.html
To be clear, these bugs can only occur if you dereference both pointers (or otherwise access their shared data) within a single scope or function. Just creating a pointer should be safe.
鉴于在任何给定的函数范围内只有两个类型化指针中的一个被取消引用,因此不会出现与严格别名相关的问题。
还有 union
方法,但无论如何。
cuMemAllocManaged
要求作为其第一个参数提供的指针是 CUdeviceptr *
类型(技术上 unsigned int *
),但使用托管内存的要点是能够操纵主机和设备上同一内存地址中的数据。因此,为了能够在主机上操作托管数据,那些 CUdeviceptr
s 必须在访问之前转换为适当的指针类型(例如 float *
或 double *
),或者主机必须存储正确类型的指针并转换为 CUdeviceptr
。据我所知,前者显然违反了严格的别名规则,但后者是否也违反了严格的别名规则,或者它是否仍然安全,因为严格的别名问题仅在通过类型双关指针显式访问数据时发生?
换句话说,即使启用了严格的别名,类似于以下代码段的模式是否安全?
float* turkey;
CUdeviceptr* goose = reinterpret_cast<CUdeviceptr*>(&turkey); // alternatively, (CUdeviceptr*)&turkey
// error checking code elided
cuMemAllocManaged(goose, sizeof(float)*10000, CU_MEM_ATTACH_GLOBAL);
// initialize turkey
// supply goose as an argument to a kernel function
cuCtxSynchronize();
// do stuff with turkey on host again
看起来这两种行为都没有问题。经过 http://www.cocoawithlove.com/2008/04/using-pointers-to-recast-in-c-is-bad.html
To be clear, these bugs can only occur if you dereference both pointers (or otherwise access their shared data) within a single scope or function. Just creating a pointer should be safe.
鉴于在任何给定的函数范围内只有两个类型化指针中的一个被取消引用,因此不会出现与严格别名相关的问题。
还有 union
方法,但无论如何。