gpt4 book ai didi

performance - CUDA性能疑虑

转载 作者:行者123 更新时间:2023-12-04 03:13:21 26 4
gpt4 key购买 nike

由于我没有收到 CUDA 论坛的回复,我在这里试试:

在 CUDA 中做了几个程序后,我现在开始获得它们的有效带宽。但是我有一些奇怪的结果,例如在下面的代码中,我可以对向量中的所有元素求和(不考虑维度),展开代码和“正常”代码的带宽似乎具有相同的中值结果(大约 3000 Gb/s)我不知道我是否做错了什么(AFAIK 程序运行良好)但从我目前阅读的内容来看,展开代码应该具有更高的带宽。

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <math.h>
#define elements 1000
#define blocksize 16


__global__ void vecsumkernel(float*input, float*output,int nelements){



__shared__ float psum[blocksize];
int tid=threadIdx.x;

if(tid + blockDim.x * blockIdx.x < nelements)
psum[tid]=input[tid+blockDim.x*blockIdx.x];
else
psum[tid]=0.0f;
__syncthreads();

//WITHOUT UNROLL

int stride;
for(stride=blockDim.x/2;stride>0;stride>>=1){
if(tid<stride)
psum[tid]+=psum[tid+stride];
__syncthreads();
}
if(tid==0)
output[blockIdx.x]=psum[0];


//WITH UNROLL
/*
if(blocksize>=512 && tid<256) psum[tid]+=psum[tid+256];__syncthreads();
if(blocksize>=256 && tid<128) psum[tid]+=psum[tid+128];__syncthreads();
if(blocksize>=128 && tid<64) psum[tid]+=psum[tid+64];__syncthreads();


if (tid < 32) {
if (blocksize >= 64) psum[tid] += psum[tid + 32];
if (blocksize >= 32) psum[tid] += psum[tid + 16];
if (blocksize >= 16) psum[tid] += psum[tid + 8];
if (blocksize >= 8) psum[tid] += psum[tid + 4];
if (blocksize >= 4) psum[tid] += psum[tid + 2];
if (blocksize >= 2) psum[tid] += psum[tid + 1];
}*/

if(tid==0)
output[blockIdx.x]=psum[0];



}

void vecsumv2(float*input, float*output, int nelements){
dim3 dimBlock(blocksize,1,1);
int i;

for(i=((int)ceil((double)(nelements)/(double)blocksize))*blocksize;i>1;i(int)ceil((double)i/(double)blocksize)){
dim3 dimGrid((int)ceil((double)i/(double)blocksize),1,1);
printf("\ni=%d\ndimgrid=%u\n ",i,dimGrid.x);

vecsumkernel<<<dimGrid,dimBlock>>>(i==((int)ceil((double)(nelements)/(double)blocksize))*blocksize ?input:output,output,i==((int)ceil((double)(nelements)/(double)blocksize))*blocksize ? elements:i);
}

}

void printVec(float*vec,int dim){
printf("\n{");
for(int i=0;i<dim;i++)
printf("%f ",vec[i]);
printf("}\n");
}

int main(){
cudaEvent_t evstart, evstop;
cudaEventCreate(&evstart);
cudaEventCreate(&evstop);


float*input=(float*)malloc(sizeof(float)*(elements));
for(int i=0;i<elements;i++)
input[i]=(float) i;


float*output=(float*)malloc(sizeof(float)*elements);



float *input_d,*output_d;

cudaMalloc((void**)&input_d,elements*sizeof(float));

cudaMalloc((void**)&output_d,elements*sizeof(float));



cudaMemcpy(input_d,input,elements*sizeof(float),cudaMemcpyHostToDevice);


cudaEventRecord(evstart,0);

vecsumv2(input_d,output_d,elements);

cudaEventRecord(evstop,0);
cudaEventSynchronize(evstop);
float time;
cudaEventElapsedTime(&time,evstart,evstop);
printf("\ntempo gasto:%f\n",time);
float Bandwidth=((1000*4*2)/10^9)/time;
printf("\n Bandwidth:%f Gb/s\n",Bandwidth);


cudaMemcpy(output,output_d,elements*sizeof(float),cudaMemcpyDeviceToHost);


cudaFree(input_d);
cudaFree(output_d);
printf("soma do vector");
printVec(output,4);



}

最佳答案

您展开的代码中有很多分支。我数了十个额外的分支。通常在 GPU 上的 warp 内分支是昂贵的,因为 warp 中的所有线程最终都在等待分支(发散)。

有关扭曲发散的更多信息,请参见此处:

http://forums.nvidia.com/index.php?showtopic=74842

您是否尝试过使用分析器查看发生了什么?

关于performance - CUDA性能疑虑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5340594/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com