まったく同じことを行う2
のカーネルがあります。そのうちの1つは共有メモリを静的に割り当て、もう1つは実行時に動的にメモリを割り当てます。私は2D配列として共有メモリを使用しています。だから動的割り当てのために、私はメモリの場所を計算するマクロを持っています。さて、2
カーネルによって生成された結果はまったく同じです。しかし、私は両方のカーネルから得たタイミングの結果は3
回離れています!スタティックメモリの割り当てははるかに高速です。私は自分のコードを投稿できないことを申し訳なく思っています。誰かがこれを正当化することはできますか?静的対動的CUDA共有メモリ割り当てのパフォーマンス
1
A
答えて
2
私は、静的共有メモリ割り当てが動的共有メモリ割り当てより高速であるという証拠はありません。上記のコメントで示されているように、再生器なしであなたの質問に答えることは不可能です。静的または動的な共有メモリの割り当てと実行時に以下のコードの少なくとも場合には、同じカーネルのタイミングは、正確に同じである。
#include <cuda.h>
#include <stdio.h>
#define BLOCK_SIZE 512
/********************/
/* CUDA ERROR CHECK */
/********************/
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
/***********************************/
/* SHARED MEMORY STATIC ALLOCATION */
/***********************************/
__global__ void kernel_static_memory_allocation(int *d_inout, int N)
{
__shared__ int s[BLOCK_SIZE];
const int tid = threadIdx.x;
const int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < N) {
s[tid] = d_inout[i];
__syncthreads();
s[tid] = s[tid] * s[tid];
__syncthreads();
d_inout[i] = s[tid];
}
}
/************************************/
/* SHARED MEMORY DYNAMIC ALLOCATION */
/************************************/
__global__ void kernel_dynamic_memory_allocation(int *d_inout, int N)
{
extern __shared__ int s[];
const int tid = threadIdx.x;
const int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < N) {
s[tid] = d_inout[i];
__syncthreads();
s[tid] = s[tid] * s[tid];
__syncthreads();
d_inout[i] = s[tid];
}
}
/********/
/* MAIN */
/********/
int main(void)
{
int N = 1000000;
int* a = (int*)malloc(N*sizeof(int));
for (int i = 0; i < N; i++) { a[i] = i; }
int *d_inout; gpuErrchk(cudaMalloc(&d_inout, N * sizeof(int)));
int n_blocks = N/BLOCK_SIZE + (N%BLOCK_SIZE == 0 ? 0:1);
gpuErrchk(cudaMemcpy(d_inout, a, N*sizeof(int), cudaMemcpyHostToDevice));
float time;
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);
kernel_static_memory_allocation<<<n_blocks,BLOCK_SIZE>>>(d_inout, N);
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaDeviceSynchronize());
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&time, start, stop);
printf("Static allocation - elapsed time: %3.3f ms \n", time);
cudaEventRecord(start, 0);
kernel_dynamic_memory_allocation<<<n_blocks,BLOCK_SIZE,BLOCK_SIZE*sizeof(int)>>>(d_inout, N);
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaDeviceSynchronize());
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&time, start, stop);
printf("Dynamic allocation - elapsed time: %3.3f ms \n", time);
}
そのための可能な理由は、という事実によるものです2つのカーネルの逆アセンブルされたコードはまったく同じで、N = 1000000;
をint N = rand();
に置き換えても変更されません。
関連する問題
- 1. 自動/静的なメモリ割り当て
- 2. C++の動的割り当てメモリ内での動的メモリ割り当て
- 3. __device/global__内のメモリを動的に割り当てるCUDAカーネル
- 4. ネットワークI/OとC++用のバッファの動的なメモリ割り当てと静的なメモリの割り当て
- 5. 2つの異なるベクトルに動的共有メモリ割り当てを使用
- 6. Cでの動的メモリ割り当て
- 7. 使用して、両方の動的に割り当てられたと静的に割り当てられた共有メモリ
- 8. 静的割り当てと動的割り当てとの比較自動割り当て
- 9. 2D動的メモリ割り当て - ObjectiveC
- 10. 動的割り当て - メモリ管理
- 11. C++動的メモリ割り当て
- 12. C++でのオブジェクトの静的および動的メモリ割り当て
- 13. .netの非静的クラスの静的変数のメモリ割り当て
- 14. CUDAカーネル内のメモリ割り当て
- 15. MinGWとの静的/動的/共有リンク
- 16. FORTRANメモリ使用率 - 静的対動的
- 17. Cuda異なるメモリ割り当て
- 18. メモリ割り当て - プロセスツリーの共通メモリ
- 19. 静的配列バッファの割り当て
- 20. コードデザイン、静的定数の割り当て
- 21. Flyweightパターンで静的インスタンスを静的インスタンスに割り当てる
- 22. Javaでは、静的メモリ割り当てと動的メモリ割り当ての両方でオブジェクトを作成できますか?
- 23. 構造体内の配列の動的メモリ割り当て
- 24. C++でのベクトルの動的メモリ割り当て
- 25. 動的にメモリを割り当てるときのアクセス違反
- 26. [C]構造の動的割り当てメモリ、GTK
- 27. 次のコードを考えると、動的メモリ割り当て
- 28. 動的なメモリ割り当てのC++文字列
- 29. __global__関数の動的メモリ割り当て
- 30. ポインタ配列の動的メモリ割り当て
NVCCで生成されたPTXコードを '-ptx'オプションで調べましたか?出力コードに明らかな違いがある場合、カーネルが速い理由を説明するのに役立ちます。 – Heatsink
コンパイラの最適化に関連する可能性があります。両方のコードを-O0オプションでコンパイルできますか? – pQB
動的サイズの計算が静的配列のサイズと同じでもよろしいですか?それが(おそらく誤って)大きくなると、カーネルの占有量を減らすことができます。実際の回答を得るには、実際の詳細を提供する必要があります。コード例です。 – harrism