2

これはかなり複雑な質問であり、私は英語を母国語としないので、私の質問を読むのに十分な忍耐力を持っていただければ幸いです。

Cudaは実際には2台のコンピューターで動作しているため、デバイス上でホストのメモリを指すことは無効です。つまり、ポインターメンバーがある場合、構造体(またはオブジェクト)をデバイスにコピーすることはできません。

この問題を解決するために、次のシステムを作成しようとしました。

  1. ポインタの代わりに整数を使用してください。整数はメモリプール内のオフセットです。整数は、ポインタのように見えるようにクラスにラップされます(「->」と「*」をオーバーロードします)。
  2. メモリプールオブジェクトは、Cudaデバイスに簡単に転送できるオブジェクトの連続配列を管理します。プールのコンテンツはホストとデバイス間で同期されるため、整数オフセットは両側で同じ意味を持ちます。

オフセットを便利に使用するには、ラップする必要があります。ホスト側では、ラッパーは次のようになります。

template<typename T>
class MemPoolPointer {
public:
    inline T* operator -> () const
    {
        return &( MemPool<T>::get_instance.get_object(_p) );
    }
    uint64_t _p;
}

ご覧のとおり、ポインタクラスはメモリプールへのグローバルアクセスを必要とします。これは通常、メモリプールをシングルトンにすることで実装されます。ただし、Cudaは静的メンバーを許可せず、__device__変数をファイルスコープに制限します。これらの制限を回避するにはどうすればよいですか?または、OpenCLを試す必要がありますか?

4

1 に答える 1

1

OPは、次のような静的クラスメソッドを使用してグローバルスコープ__device__変数をラップすることにより、これを解決できました。

class FooBar;
__device__ FooBar* FOOBAR_DEVICE_POOL;
class FooBar
{
    __device__ static FooBar& DEVICE_GET(uint64_t p);
}

template<typename T>
class MemPoolPointer {
public:
    inline T* operator -> () const
    {
#ifdef __CUDA_ARCH__
        return &( T::DEVICE_GET(_p) );
#else
        return &( MemPool<T>::get_instance.get_object(_p) );
#endif
    }
    uint64_t _p;
}

[この回答は、CUDAタグの未回答のキューから質問を削除するためのコミュニティWikiエントリとして追加されました]

于 2016-11-14T10:32:40.123 に答える