C++ Cuda矩阵复制程序非常慢
这是:C++ Cuda矩阵复制程序非常慢,c++,c,cuda,gpu,C++,C,Cuda,Gpu,这是: #包括 #包括 那边选择的答案没有指定数据是如何生成的 从主机复制到设备。有人能展示一下如何使用 cudaMallocPitch和cudaMemcpy2D功能?我在找那个 在内核和 将2D阵列从主机复制到设备的正确方法 你只运行一个CUDA线程。(实际上,仔细观察,您在多个线程中运行相同的代码,但结果是相同的:您并没有真正利用GPU硬件) 理想情况下,您需要运行数百或数千个并发线程才能获得最佳性能。一种方法是每个输出元素有一个线程,然后在每个线程中使用网格、块和线程ID来确定要处理的输出
#包括
#包括
那边选择的答案没有指定数据是如何生成的
从主机复制到设备。有人能展示一下如何使用
cudaMallocPitch和cudaMemcpy2D功能?我在找那个
在内核和
将2D阵列从主机复制到设备的正确方法
你只运行一个CUDA线程。(实际上,仔细观察,您在多个线程中运行相同的代码,但结果是相同的:您并没有真正利用GPU硬件)
理想情况下,您需要运行数百或数千个并发线程才能获得最佳性能。一种方法是每个输出元素有一个线程,然后在每个线程中使用网格、块和线程ID来确定要处理的输出元素。查看CUDA SDK中的示例,了解CUDA并行处理的一般模式。因此我需要对CopyData进行一些重大更改。我说的对吗?不是很激烈,但你需要摆脱循环,让每个线程处理一个输出元素。@Paul\R我的代码是基于我所看到的。Vihari给出的示例是否不正确?请仔细查看您链接的代码-它没有在内核代码中使用循环-它使用块和线程索引来确定要处理的元素。@Paul\R我在页面底部讨论的是代码。它在内核代码“CopyData”中有一个for循环。
#include<stdio.h>
#include<assert.h>
void verify(float * A, float * B, int size);
__global__ void CopyData(float *d_array, float* d_dest_array, size_t pitch, int cols, int rows)
{
for(int i=0; i<rows; i++){
float *rowData = (float*)(((char*)d_array) + (i*pitch));
for(int j=0; j<cols; j++){
d_dest_array[i*cols+j] = *(rowData+j);
}
}
}
int main(int argc, char **argv)
{
int row, col, i, j;
float time1, time2;
float *d_array; // dev arr which mem will be alloc to
float *d_dest_array; // dev arr that will be a copy
size_t pitch; // ensures correct data struc alignm
if(argc != 3)
{
printf("Usage: %s [row] [col]\n", argv[0]);
return 1;
}
row = atoi(argv[1]);
col = atoi(argv[2]);
float *h1_array = new float[col*row];
float *h2_array = new float[col*row];
float *h_ori_array = new float[col*row];
for (i = 0; i<row; i++){
for(j = 0; j<col; j++){
h_ori_array[i*col+j] = i*col + j;
}
}
cudaEvent_t start, stop;
cudaMallocPitch(&d_array, &pitch, col*sizeof(float), row);
cudaMalloc(&d_dest_array, col*row*sizeof(float));
cudaMemcpy2D(d_array, pitch, h_ori_array, col*sizeof(float), col*sizeof(float), row, cudaMemcpyHostToDevice);
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);
//CopyData<<<100, 512>>>(d_array, d_dest_array, pitch, col, row);
for (i = 0; i<row; i++){
for(j = 0; j<col; j++){
h1_array[i*col+j] = h_ori_array[i*col+j];
}
}
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&time1, start, stop);
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);
CopyData<<<row*col/512, 512>>>(d_array, d_dest_array, pitch, col, row);
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&time2, start, stop);
cudaMemcpy2D(h2_array, pitch, d_dest_array, col*sizeof(float), col*sizeof(float), row, cudaMemcpyDeviceToHost);
verify(h1_array, h2_array, row*col);
free(h1_array); free(h2_array); free(h_ori_array);
cudaFree(d_array); cudaFree(d_dest_array);
printf("Exec time in ser = %f, par = %f ms with pitch %d", time1, time2, (int)pitch);
return 0;
}
void verify(float * A, float * B, int size)
{
for (int i = 0; i < size; i++)
{
assert(A[i]==B[i]);
}
printf("Correct!");
}