4. Reduction
以求n数之和为例,讲述规约问题。
串行规约
即直接遍历,时间复杂度为\(O(n)\)。
int sum = 0;
for (int& x : v) {
sum += x;
}
并行规约
可以采用分治策略,例如计算[1, 2, 3, 4]的和,可以一个线程计算1+2,另一个线程计算3+4,再把结果进行合并。
分治总运算次数为\(O(nlogn)\),假设使用\(n\)个线程,时间复杂度就会降至\(O(logn)\)。
#include <iostream>
#include <cuda_runtime.h>
__global__ void sum(int* arr, int* output, int n) {
__shared__ int tmp[256];
int idx = blockDim.x * blockIdx.x + threadIdx.x;
if (idx >= n) return;
tmp[idx] = arr[idx];
__syncthreads();
for (int i = 1; i < n; i <<= 1) {
// i为当前轮次合并的规模 例如i=2 表示2个元素的结果 合并为4个元素的结果
if (threadIdx.x % (i * 2) >= i) return;
tmp[threadIdx.x] += tmp[threadIdx.x + i];
__syncthreads();
}
if (threadIdx.x == 0) {
*output = tmp[0];
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int* darr;
int* output = (int*)malloc(sizeof(int));
int* doutput;
cudaMalloc(&darr, sizeof(arr));
cudaMemcpy(darr, arr, sizeof(arr), cudaMemcpyHostToDevice);
cudaMalloc(&doutput, sizeof(int));
sum<<<1, 10>>>(darr, doutput, sizeof(arr) / sizeof(int));
cudaMemcpy(output, doutput, sizeof(int), cudaMemcpyDeviceToHost);
printf("output = %d\n", *output);
cudaFree(darr);
cudaFree(doutput);
free(output);
return 0;
}
任务
编写矩阵乘法计算程序,使用数据集链接: https://pan.baidu.com/s/1ybdubBDsNa5HBXsIt3loTQ?pwd=cuda 提取码: cuda进行测试。
要求:
- 使用朴素的矩阵乘法计算方式,不要使用Strassen算法、Coppersmith-Winograd算法等高速算法,也就是要从并行的角度提速而非矩阵乘法计算方式的角度提速。
- 输入输出使用
printf和scanf,不要使用cin和cout或者快读快写。 - 使用shell进行测试。
例:
#! /bin/sh
nvcc matrix.cu -o matrix
start=$(date +%s%3N)
for i in $(seq 1 15)
do
./matrix < ./data/$i >> ./out
done
end=$(date +%s%3N)
time_ms=$(($end - $start))
seconds=$((time_ms / 1000))
ms=$((time_ms % 1000))
echo "time: ${seconds}.${ms} s"
对于每个测试文件,输入格式如下:
第一行输入三个整数\(a\)、\(b\)、\(c\),表示矩阵\(A\)大小为\(a\times b\),矩阵\(B\)大小为\(b\times c\),\(0\le a,b,c \le 4999\)。
之后\(a\)行,每行有\(b\)个整数,其中第\(i\)行第\(j\)个整数表示表示\(A_{i,j}(1\le A_{i,j}\le 1000)\)。
之后\(b\)行,每行有\(c\)个整数,其中第\(i\)行第\(j\)个整数表示表示\(B_{i,j}(1\le B_{i,j}\le 1000)\)。
对于每个测试文件,输出格式如下:
输出\(a\)行,每行有\(c\)个整数,其中第\(i\)行第\(j\)个整数表示\((A\times B)_{i,j}\)。如果\(a,b,c\)中有\(0\),则只输出一个\(0\)即可。

浙公网安备 33010602011771号