Я не опытный программист CUDA. У меня такая проблема. Я пытаюсь загрузить плиту (32x32) большой матрицы (10K * 10K) из глобальной памяти в разделяемую память, и я синхронизирую ее, когда это происходит. Я понял, что если я загружу его в частную память (регистры), он загружается в 4-5 раз быстрее, чем загрузка общей памяти.В cuda загрузка в общую память происходит медленнее загрузки в регистры
__global__ void speedtest(float *vel,int nx) {
int globalx = blockDim.x * blockIdx.x + threadIdx.x+pad;
int globalz = blockDim.y * blockIdx.y + threadIdx.y+pad;
int localx=threadIdx.x;
int localz=threadIdx.y;
float ptest;
__shared__ float stest[tile][tile];
//stest[localz][localx]=vel[globalz*nx+globalx]; //load to shared memory
ptest=vel[globalz*nx+globalx]; //load to private memory
__syncthreads();
}
Я закомментировать STest и Ptest по одному и рассчитать время, прошедшее с cudaeventrecord. stest взял 3,2 мс и ptest взял 0,75 м для загрузки. Что я делаю не так? Сроки должны быть очень похожими? Что мне не хватает?
Конфигурация: Cuda 7.5, gtx 980, только 32-битные переменные и вычисления, нет конкретной цели, я просто играю с ней.
Я вывешиваю пример кода в соответствии с просьбой
#include<stdio.h>
#include <math.h>
#define tile 32
#include <helper_cuda.h>
void makeittwo(float *array,int nz,int nx)
{
//this just assigns a number into the vector
int n2;
n2=nx*nz;
for (int i=0;i<n2;i++)
array[i]=2000;
}
__global__ void speedtest(float *vel,int nx,int nz) {
int globalx = blockDim.x * blockIdx.x + threadIdx.x;
int globalz = blockDim.y * blockIdx.y + threadIdx.y;
int localx=threadIdx.x;
int localz=threadIdx.y;
float ptest; //declarations
__shared__ float stest[tile][tile];
if (globalx<nx && globalz<nz){
stest[localz][localx]=vel[globalz*nx+globalx]; //shared variable
//ptest=vel[globalz*nx+globalx]; //private variable
//comment out ptest and stest one by one to test them
}
__syncthreads();
}
int main(int argc,char *argv)
{
int nx,nz,N;
float *vel;
nz=10000;nx=10000; //matrix dimensions
N=nz*nx; //convert matrix into vector
checkCudaErrors(cudaMallocHost(&vel,sizeof(float)*N)); //using pinned memory
makeittwo(vel,nz,nx);
dim3 dimBlock(tile,tile);
dim3 dimGrid;
int blockx=dimBlock.x;
int blockz=dimBlock.y;
dimGrid.x = (nx + blockx - 1)/(blockx);
dimGrid.y = (nz + blockz - 1)/(blockz);
float *d_vel;
checkCudaErrors(cudaMalloc(&d_vel,sizeof(float)*(N))); //copying to device
checkCudaErrors(cudaMemcpy(d_vel, vel, sizeof(float)*(N), cudaMemcpyHostToDevice));
cudaEvent_t start,stop;
float elapsedTime;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start,0);
speedtest<<<dimGrid,dimBlock>>>(d_vel,nx,nz); //calling the function
cudaEventRecord(stop,0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime,start,stop);
printf("time=%3.3f ms\n",elapsedTime);
checkCudaErrors(cudaMemcpy(vel, d_vel, sizeof(float)*N, cudaMemcpyDeviceToHost));
//calling the matrix back to check if all went well (this fails if out of bound calls are made)
cudaDeviceReset();
}
всегда предлагайте [Минимальный, полный и проверенный пример] (http: // stackoverflow.com/help/mcve) –
Вот ссылка на файл https://www.dropbox.com/s/l09byvk9ghba078/speedtestpost.cu?dl=0 вы можете скомпилировать его с помощью nvcc -w speedtestpost.cu – coercion
, а скорее включить содержимое файла прямо в ваш вопрос вместо ссылки на ресурсы вне сайта –