グローバルメモリの内容は、グリッドのすべてのスレッドに表示されます。すべてのスレッドは、グローバルメモリの任意の場所に対して読み取りと書き込みを行うことができます。
共有メモリは、グリッドのブロックごとに分離されています。ブロックのどのスレッドも、そのブロックの共有メモリに対して読み取りと書き込みを行うことができます。あるブロックのスレッドは、別のブロックの共有メモリにアクセスできません。
cudaMalloc
常にグローバルメモリを割り当てます。
- グローバルメモリはデバイス上にあります。
- 明らかに、すべてのメモリにはサイズ制限があります。グローバルメモリは、使用しているGPUのDRAMの合計量です。たとえば、1536 MBのDRAM、つまり1536MBのグローバルメモリを搭載したGTX460Mを使用しています。共有メモリはデバイスアーキテクチャによって指定され、ブロックごとに測定されます。コンピューティング機能1.0〜1.3のデバイスには
16 KB/Block
、48 KB/Block
デフォルトで共有メモリがあります。
- 共有メモリは、グローバルメモリよりもアクセスが非常に高速です。これは、ブロックのスレッド間で共有されるローカルキャッシュのようなものです。
- いいえ。ホストから起動されたカーネルに渡すことができるのは、グローバルメモリアドレスのみです。最初の例では、変数は共有メモリから読み取られますが、2番目の例では、変数はグローバルメモリから読み取られます。
アップデート:
Compute Capability 7.0(Volta Architecture)のデバイスでは、次の条件が満たされている場合、ブロックあたり最大96KBの共有メモリを割り当てることができます。
- 共有メモリは動的に割り当てられます
- カーネルを起動する前に、動的共有メモリの最大サイズを次の関数
cudaFuncSetAttribute
を使用して指定します。
__global__ void MyKernel(...)
{
extern __shared__ float shMem[];
}
int bytes = 98304; //96 KB
cudaFuncSetAttribute(MyKernel, cudaFuncAttributeMaxDynamicSharedMemorySize, bytes);
MyKernel<<<gridSize, blockSize, bytes>>>(...);