コマンドライン引数から取得した値をカーネルに渡すことで、Cuda アプリケーションをもう少し動的にしようとしています。
アプリケーションは複数のカーネルを呼び出し、ブロックとグリッドのサイズも最大化します。アプリケーションを実行しようとすると、次の結果が得られます。
- ハードコーディングされた値: .96 秒
- カーネルの初期化時に値を渡す: 3.48 秒
- を宣言し
__device__ int
、値に設定: 3.48 秒
実行時に値が入力されると、プログラムの残りの部分で一定のままになります。
2 つの 3.48 秒の時間は、変数自体へのアクセスによるものです。変数をハードコードされた整数に置き換えると、実行時間が大幅に短縮されます。この値は非常に頻繁にアクセスされるため、ハードコードされた値と同様の速度を維持しながら、変数へのアクセスのコストを削減する方法があるかどうか疑問に思っていました。変数を使用してこれを高速化することは可能ですか?
3.6x 遅いことは重要ですか? 並べ替え。これは、はるかに大きなもののほんの一部です。
どんな助けでも大歓迎です。
*2.0 ハードウェアを実行しています。
編集:これは私が経験している違いの例です:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <ctime>
using namespace std;
clock_t start;
__device__ int x;
__global__ void setNum(int i)
{
x = i;
return;
}
__device__ void d_swap(int * a, int * b)
{
int temp = *a;
*a = *b;
*b = temp;
}
__device__ void other(int n, int * vec)
{
int i;
for(i = 0; i < n; ++i) vec[i] = i;
for (int j = 0; j < 5; j++)
for(i = 1; i < n-1; ++i)
d_swap(&vec[i], &vec[i-1]);
}
__global__ void Pressure(int i)
{
int a[12];
other(x, a);
//other(12,a);
}
int main(int argc, char * argv[])
{
if (argc != 2)
{
fprintf(stderr,"Invalid number of arguments.\n");
exit(1);
}
int num = atoi(argv[1]);
cudaSetDevice(1);
cudaMemset(&x, num, sizeof(int));
setNum<<< 1 , 1>>>( num );
cudaError_t cuda_status = cudaDeviceSynchronize();
if (cuda_status != cudaSuccess) {
printf("No dice\n");
exit(1);
}
int results = 0;
cudaMemcpyFromSymbol(&results, x, sizeof(int));
printf("Value of x: %i\n", results);
start = clock();
for (int i = 0; i < 8; i++)
Pressure<<<65535, 1024>>>(i);
cuda_status = cudaDeviceSynchronize();
printf("Result: %f\n", (float)(clock()-start)/CLOCKS_PER_SEC);
return 0;
}
以下でコンパイル:nvcc -m64 -gencode arch=compute_20,code=sm_20 -o test test.cu
実行: ./test 12
(12 は x 変数を設定します)
コメントアウトされたコード ブロックに注意してください。
実行中other(x, a);
、私は得る1.370000
実行中other(12,a);
、私は得る0.020000