私が理解していることは、CUDAではブロック数が並列化されているので時間が増えることはないが、私のコードではブロック数を倍にすれば時間も倍増するということです。なぜクワのブロック数を増やすと時間が増えますか?
#include <cuda.h>
#include <curand.h>
#include <curand_kernel.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define num_of_blocks 500
#define num_of_threads 512
__constant__ double y = 1.1;
// set seed for random number generator
__global__ void initcuRand(curandState* globalState, unsigned long seed){
int idx = threadIdx.x + blockIdx.x * blockDim.x;
curand_init(seed, idx, 0, &globalState[idx]);
}
// kernel function for SIR
__global__ void test(curandState* globalState, double *dev_data){
// global threads id
int idx = threadIdx.x + blockIdx.x * blockDim.x;
// local threads id
int lidx = threadIdx.x;
// creat shared memory to store seeds
__shared__ curandState localState[num_of_threads];
// shared memory to store samples
__shared__ double sample[num_of_threads];
// copy global seed to local
localState[lidx] = globalState[idx];
__syncthreads();
sample[lidx] = y + curand_normal_double(&localState[lidx]);
if(lidx == 0){
// save the first sample to dev_data;
dev_data[blockIdx.x] = sample[0];
}
globalState[idx] = localState[lidx];
}
int main(){
// creat random number seeds;
curandState *globalState;
cudaMalloc((void**)&globalState, num_of_blocks*num_of_threads*sizeof(curandState));
initcuRand<<<num_of_blocks, num_of_threads>>>(globalState, 1);
double *dev_data;
cudaMalloc((double**)&dev_data, num_of_blocks*sizeof(double));
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
// Start record
cudaEventRecord(start, 0);
test<<<num_of_blocks, num_of_threads>>>(globalState, dev_data);
// Stop event
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
float elapsedTime;
cudaEventElapsedTime(&elapsedTime, start, stop); // that's our time!
// Clean up:
cudaEventDestroy(start);
cudaEventDestroy(stop);
std::cout << "Time ellapsed: " << elapsedTime << std::endl;
cudaFree(dev_data);
cudaFree(globalState);
return 0;
}
テスト結果は次のとおりです。
number of blocks: 500, Time ellapsed: 0.39136.
number of blocks: 1000, Time ellapsed: 0.618656.
ので時間が増加することの理由は何ですか?それは定数メモリにアクセスするか、または共有メモリからグローバルメモリにデータをコピーするためですか?それはそれを最適化するいくつかの方法ですか?
ご協力いただきありがとうございます。私が使用しているGPUはTesla K80です。そこにはマルチプロセッサのストリーミング数を知ることができますか?さらに、GPUを1つのみ使用する場合、2つのGPUを使用してコードを実行すると意味があります。つまり、各GPUが同時に実行でき、GPUが増えるほど時間がかかりますか? –
テスラのラインナップについては、GeForceカードよりもその情報が少し難しくなります。後者の場合、Webサイトで仕様を調べるだけです。私はプロのカードに似た情報を見つけることはできませんでした。なぜなら、Nvidiaのウェブサイト上のTeslaマーケティング資料は、読者が理解できないという明白な前提で購入決定をするマネージャーに向けられているようです技術仕様書)。 – tera
あなたは[K80が2496単精度「CUDAコア」を持っている]という事実(http://international.download.nvidia.com/pdf/kepler/TeslaK80-datasheet)を組み合わせて情報を得ることができます。pdf)とそれに加えて[1つのGK110/GK210 SMはSM1個につき192の単精度「CUDAコア」を持っています(http://images.nvidia.com/content/pdf/tesla/NVIDIA-Kepler-GK110-GK210-Architecture -Whitepaper.pdf)、K80上の2つのGPUのそれぞれに13個のSMがあることがわかりました。 – tera