Código
Uma aplicação interessante é o algoritmo de produto escalar entre dois vetores X e Y de tamanho N. O produto escalar é o somatório dos produtos dos elementos de mesmo índice, exemplo:
- ProdutoEscalar = x[0]*y[0] + x[1]*y[1] + ... + x[n]*y[n]
CUDA pode paralelizar o somatório dos produtos como mostrado por VASCONCELLOS.
int main(){
cudaMalloc((void**) &d_A, mem_size); //alocação da memória
cudaMalloc((void**) &dev, sizeof(unsigned int)); //na GPU
cudaMemcpy(d_A, h_A, mem_size, cudaMemcpyHostToDevice); //Cópia dos dados
cudaMemcpy(d_B, h_B, mem_size, cudaMemcpyHostToDevice); //para a mem. da GPU
mult<<>>(d_C, d_A, d_B); //Execução do
soma<<>>(d_C, d_Result); //código
cudaMemcpy(host, dev, sizeof(unsigned int), cudaMemcpyDeviceToHost); //Liberação da
cudaFree(d_A); //memória da GPU
}
__global__ void mult(unsigned int* C, unsigned int* A, unsigned int* B) { // kernel
int i = blockDim.x * blockIdx.x + threadIdx.x; //funções executadas
C[i] = A[i] * B[i]; //pelo GPU, chamada
} //pela CPU
__global__ void soma(unsigned int* C, unsigned int* total) { //kernel
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
__shared__ unsigned int x[VECTOR_LENGTH/THREAD_BLOCKS]; //declara vetor compartilhado
x[tid] = C[i];
__syncthreads(); //sincroniza as threads
for(int s=blockDim.x/2; s>0; s=s/2) {
if(tid < s) x[tid] += x[tid + s];
__syncthreads(); //sincroniza as threads
}
if (tid == 0)
atomicAdd(total, x[0]);
}