CUDA:将对象加载到共享内存中是否合理?

时间:2015-06-22 14:08:25

标签: c++ cuda

我有一个对象可以被块的所有线程访问,因此我计划将它存储在共享内存中。我创建了附加类,将对象从全局内存加载到共享内存中。

这个想法很简单:每个线程加载一个对象的单词。共享内存不能是成员,因此它是在外部定义的。

这堂课到目前为止似乎有效。 但这是一种合理的方法,还是我可能会遇到问题?我不是要求对编码风格进行一般性讨论,而是针对危险的非显而易见的陷阱或重大缺陷。

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);

1 个答案:

答案 0 :(得分:2)

回答你的问题:对于你正在做的事情来定义明确(从C ++的角度来看),你的类型必须满足TriviallyCopyable的要求:

  

唯一可复制的类型是标量类型,简单的可复制类,以及此类类型/类的数组(可能是const限定的,但不是volatile限定的)。

     

一个简单的可复制类是

的类      
      
  1. 没有非平凡的拷贝构造函数(这也不需要虚函数或虚拟库)
  2.   
  3. 没有非平凡的移动构造函数
  4.   
  5. 没有非平凡的副本分配运算符
  6.   
  7. 没有非平凡的移动分配操作员
  8.   
  9. 有一个简单的析构函数
  10.   

在主机代码中,您可以使用特征std::is_trivially_copyable来测试T是否符合条件。

请注意,您的代码目前不包含内存屏障,因此会受到竞争条件的影响。

您还必须确保正在加载的对象在WORDTYPE上对齐。