我有一个对象可以被块的所有线程访问,因此我计划将它存储在共享内存中。我创建了附加类,将对象从全局内存加载到共享内存中。
这个想法很简单:每个线程加载一个对象的单词。共享内存不能是成员,因此它是在外部定义的。
这堂课到目前为止似乎有效。 但这是一种合理的方法,还是我可能会遇到问题?我不是要求对编码风格进行一般性讨论,而是针对危险的非显而易见的陷阱或重大缺陷。
template <class T>
class SharedMemoryObjectLoader{
public:
// each thread will load one word
using WORDTYPE = int;
// compute the number of words (rounding up)
static constexpr int N_WORDS = (sizeof(T) + sizeof(WORDTYPE) - 1) / sizeof(WORDTYPE);
// load the object behind 'globalPtr' into shared memory location 'smemPtr'
__device__ static T* load(WORDTYPE* smemPtr, T* globalPtr){
WORDTYPE* smemWordPtr = reinterpret_cast<WORDTYPE*>(smemPtr);
WORDTYPE* globalWordPtr = reinterpret_cast<WORDTYPE*>(globalPtr);
if(N_WORDS > blockDim.x){
// we assume that an object has less words than the number of threads
assert(0);
}
else{
if(N_WORDS > threadIdx.x){
// each thread with an id smaller than the number of words will load one word
smemWordPtr[threadIdx.x] = globalWordPtr[threadIdx.x];
}
}
return reinterpret_cast<T*>(smemPtr);
}
};
加载对象:
using Loader = CommandDataPerBlockLoader<Obj>
__shared__ typename Loader::WORDTYPE shMem[Loader::N_WORDS];
Obj* shObj = CommandDataPerBlockLoader::load(shMem, objPtrInGlobalMem);
答案 0 :(得分:2)
回答你的问题:对于你正在做的事情来定义明确(从C ++的角度来看),你的类型必须满足TriviallyCopyable
的要求:
唯一可复制的类型是标量类型,简单的可复制类,以及此类类型/类的数组(可能是const限定的,但不是volatile限定的)。
一个简单的可复制类是
的类
- 没有非平凡的拷贝构造函数(这也不需要虚函数或虚拟库)
- 没有非平凡的移动构造函数
- 没有非平凡的副本分配运算符
- 没有非平凡的移动分配操作员
- 有一个简单的析构函数
醇>
在主机代码中,您可以使用特征std::is_trivially_copyable
来测试T
是否符合条件。
请注意,您的代码目前不包含内存屏障,因此会受到竞争条件的影响。
您还必须确保正在加载的对象在WORDTYPE
上对齐。