/************************************************************************** 行/列求和函数。按下面的要求编辑此文件: 1. 将你的学号、姓名,以注释的方式写到下面; 2. 实现不同版本的行列求和函数; 3. 编辑rc_fun_rec rc_fun_tab数组,将你的最好的答案 (最好的行和列求和、最好的列求和)作为数组的前两项 ***************************************************************************/ /* 学号:202302723005 姓名:程景愉 */ #include #include #include "rowcol.h" #include #include /* 参考的列求和函数实现 */ /* 计算矩阵中的每一列的和。请注意对于行和列求和来说,调用参数是 一样的,只是第2个参数不会用到而已 */ void c_sum(matrix_t M, vector_t rowsum, vector_t colsum) { int i,j; for (j = 0; j < N; j++) { colsum[j] = 0; for (i = 0; i < N; i++) colsum[j] += M[i][j]; } } /* 参考的列和行求和函数实现 */ /* 计算矩阵中的每一行、每一列的和。 */ void rc_sum(matrix_t M, vector_t rowsum, vector_t colsum) { int i,j; for (i = 0; i < N; i++) { rowsum[i] = colsum[i] = 0; for (j = 0; j < N; j++) { rowsum[i] += M[i][j]; colsum[i] += M[j][i]; } } } /* CUDA优化的列求和函数 */ void cuda_c_sum(matrix_t M, vector_t rowsum, vector_t colsum) { // 分配设备内存 int *d_M, *d_colsum; cudaMalloc(&d_M, N * N * sizeof(int)); cudaMalloc(&d_colsum, N * sizeof(int)); // 将数据从主机复制到设备 cudaMemcpy(d_M, M, N * N * sizeof(int), cudaMemcpyHostToDevice); // 定义CUDA核函数 dim3 blockDim(256); dim3 gridDim((N + blockDim.x - 1) / blockDim.x); // 启动核函数 cudaColumnSum<<>>(d_M, d_colsum); // 将结果从设备复制回主机 cudaMemcpy(colsum, d_colsum, N * sizeof(int), cudaMemcpyDeviceToHost); // 释放设备内存 cudaFree(d_M); cudaFree(d_colsum); } /* CUDA优化的行列求和函数 */ void cuda_rc_sum(matrix_t M, vector_t rowsum, vector_t colsum) { // 分配设备内存 int *d_M, *d_rowsum, *d_colsum; cudaMalloc(&d_M, N * N * sizeof(int)); cudaMalloc(&d_rowsum, N * sizeof(int)); cudaMalloc(&d_colsum, N * sizeof(int)); // 将数据从主机复制到设备 cudaMemcpy(d_M, M, N * N * sizeof(int), cudaMemcpyHostToDevice); // 定义CUDA核函数 dim3 blockDim(256); dim3 gridDim((N + blockDim.x - 1) / blockDim.x); // 启动核函数 cudaRowColSum<<>>(d_M, d_rowsum, d_colsum); // 将结果从设备复制回主机 cudaMemcpy(rowsum, d_rowsum, N * sizeof(int), cudaMemcpyDeviceToHost); cudaMemcpy(colsum, d_colsum, N * sizeof(int), cudaMemcpyDeviceToHost); // 释放设备内存 cudaFree(d_M); cudaFree(d_rowsum); cudaFree(d_colsum); } /* CUDA核函数 - 列求和 */ __global__ void cudaColumnSum(int *M, int *colsum) { int col = blockIdx.x * blockDim.x + threadIdx.x; if (col < N) { colsum[col] = 0; for (int row = 0; row < N; row++) { colsum[col] += M[row * N + col]; } } } /* CUDA核函数 - 行列求和 */ __global__ void cudaRowColSum(int *M, int *rowsum, int *colsum) { int idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < N) { // 计算行和 rowsum[idx] = 0; for (int j = 0; j < N; j++) { rowsum[idx] += M[idx * N + j]; } // 计算列和 colsum[idx] = 0; for (int i = 0; i < N; i++) { colsum[idx] += M[i * N + idx]; } } } /* 这个表格包含多个数组元素,每一组元素(函数名字, COL/ROWCOL, "描述字符串") COL表示该函数仅仅计算每一列的和 ROWCOL表示该函数计算每一行、每一列的和 将你认为最好的两个实现,放在最前面。 比如: {my_c_sum1, "超级垃圾列求和实现"}, {my_rc_sum2, "好一点的行列求和实现"}, */ rc_fun_rec rc_fun_tab[] = { /* 第一项,应当是你写的最好列求和的函数实现 */ {cuda_c_sum, COL, "CUDA optimized column sum"}, /* 第二项,应当是你写的最好行列求和的函数实现 */ {cuda_rc_sum, ROWCOL, "CUDA optimized row and column sum"}, {c_sum, COL, "Column sum, reference implementation"}, {rc_sum, ROWCOL, "Row and column sum, reference implementation"}, /* 下面的代码不能修改或者删除!!表明数组列表结束 */ {NULL,ROWCOL,NULL} };