【高级程序设计 实验报告12】GPU并行1

发布时间:2026/5/17 17:30:58

【高级程序设计 实验报告12】GPU并行1 上一篇【高级程序设计 实验报告11】矩阵并行计算目录一、实验目的二、实验内容实验步骤代码实验心得一、实验目的了解简单的GPU并行计算实验环境Visual Studio2022Windows11二、实验内容1、了解GPU环境配置2、查看电脑CUDA的配置3、在Visual Studio2022写一个.cu函数查看电脑的配置实验步骤1、提前给电脑配置GPU环境,在cmd控制台中输入命令nvida-smi敲回车键如下图1所示Nvcc -V上图中会显示cuda版本则代表电脑有此环境。创建一个win32项目起一个名字为VS.CU3、然后图二中找到生成自定义并打开图二如果你的环境配置是CUDA10.1版本就勾选10.1版本勾选相应的CUDA版本如图三所示代码#includestdlib.h // 简单的核函数将数组每个元素增加b __global__ void kernelAddConstant(int *g_a, const int b) { int idx blockIdx.x * blockDim.x threadIdx.x; g_a[idx] b; } // 验证函数检查数组每个元素是否等于其索引值加b int correctResult(int *data, const int n, const int b) { for (int i 0; i n; i) if (data[i] ! i b) return 0; return 1; } int main(int argc, char *argv[]) { int num_gpus 0; // CUDA GPU设备数量 ///////////////////////////////////////////////////////////////// // 检测可用的CUDA GPU设备数量 // cudaGetDeviceCount(num_gpus); if (num_gpus 1) { printf(未检测到可用的CUDA设备\n); return 1; } ///////////////////////////////////////////////////////////////// // 显示CPU和GPU配置信息 // printf(主机CPU数量:\t%d\n, omp_get_num_procs()); printf(CUDA设备数量:\t%d\n, num_gpus); for (int i 0; i num_gpus; i) { cudaDeviceProp dprop; cudaGetDeviceProperties(dprop, i); printf( %d: %s\n, i, dprop.name); } printf(---------------------------\n); ///////////////////////////////////////////////////////////////// // 初始化数据 // unsigned int n num_gpus * 8192; // 总数据量 unsigned int nbytes n * sizeof(int); int *a 0; // 主机端数据指针 int b 3; // 数组元素增量值 a (int*)malloc(nbytes); if (0 a) { printf(无法分配主机内存\n); return 1; } for (unsigned int i 0; i n; i) a[i] i; // 初始化数组值为索引值 //////////////////////////////////////////////////////////////// // 创建与CUDA设备数量相同的CPU线程 // 每个CPU线程控制一个不同的设备处理对应的数据部分。 // 也可以创建比GPU设备更多的CPU线程例如设置为2*num_gpus // 此时多个CPU线程会共享同一个设备。 // 注意在omp parallel块内声明的变量对每个CPU线程都是独立的 // omp_set_num_threads(num_gpus); // CPU线程数 GPU设备数 // omp_set_num_threads(2*num_gpus); // 可以尝试设置为GPU设备数的两倍 #pragma omp parallel { unsigned int cpu_thread_id omp_get_thread_num(); unsigned int num_cpu_threads omp_get_num_threads(); // 为当前CPU线程设置并检查对应的CUDA设备 int gpu_id -1; cudaSetDevice(cpu_thread_id % num_gpus); // 取模运算允许CPU线程数多于GPU设备数 cudaGetDevice(gpu_id); printf(CPU线程 %d (共%d个) 正在使用CUDA设备 %d\n, cpu_thread_id, num_cpu_threads, gpu_id); int *d_a 0; // 当前设备内存指针 int *sub_a a cpu_thread_id * n / num_cpu_threads; // 当前线程处理的数据段起始地址 unsigned int nbytes_per_kernel nbytes / num_cpu_threads; dim3 gpu_threads(128); // 每个线程块128个线程 dim3 gpu_blocks(n / (gpu_threads.x * num_cpu_threads)); // 计算需要的线程块数量 // 设备内存操作 cudaMalloc((void**)d_a, nbytes_per_kernel); cudaMemset(d_a, 0, nbytes_per_kernel); cudaMemcpy(d_a, sub_a, nbytes_per_kernel, cudaMemcpyHostToDevice); kernelAddConstant gpu_blocks, gpu_threads (d_a, b); // 调用核函数 // 将结果拷贝回主机 cudaMemcpy(sub_a, d_a, nbytes_per_kernel, cudaMemcpyDeviceToHost); cudaFree(d_a); // 释放设备内存 } printf(---------------------------\n); // 检查CUDA操作是否出错 if (cudaSuccess ! cudaGetLastError()) printf(%s\n, cudaGetErrorString(cudaGetLastError())); //////////////////////////////////////////////////////////////// // 验证计算结果 // if (correctResult(a, n, b)) printf(测试通过\n); else printf(测试失败\n); free(a); // 释放主机内存 cudaThreadExit(); // 清理CUDA运行时环境 return 0; }实验心得本次GPU并行计算实验让我首次近距离接触GPU并行编程的核心逻辑与实操流程从环境配置到代码调试从理论认知到实践应用每一个环节都让我对并行计算技术有了更深入的理解也深刻体会到GPU在高性能计算领域的独特优势同时收获了宝贵的实操经验与问题解决能力。实验的核心目标是了解简单的GPU并行计算掌握GPU环境配置方法通过编写CUDA程序查看电脑的GPU配置并实现简单的并行计算任务。相较于此前的CPU并行实验GPU并行计算依托其多核架构能实现更高效的任务并行处理这也让我对“并行计算”的理解从单一的CPU并行拓展到GPU与CPU协同并行的更广阔维度。实验初期的环境配置的环节让我认识到GPU并行计算对环境的严格要求。通过在CMD控制台输入nvidia-smi和nvcc -V命令查看CUDA版本与设备信息确认环境配置是否成功这一步骤看似简单却直接决定了后续实验的顺利开展。在创建Visual Studio 2022项目时需通过“生成自定义”勾选对应版本的CUDA确保项目能正常识别GPU设备这让我明白GPU并行编程的前提是环境的精准配置任何一个细节的疏漏都可能导致实验失败培养了我严谨细致的实验态度。代码编写与调试是本次实验的核心环节。实验中编写的CUDA程序核心包含核函数、验证函数与主函数其中核函数作为GPU并行计算的核心负责将任务分配到GPU的多个线程中执行。通过__global__关键字声明核函数利用blockIdx.x、blockDim.x和threadIdx.x确定线程索引实现数组元素的并行增量操作这让我直观理解了GPU线程的组织方式——线程块block与线程thread的层级结构以及如何通过索引分配任务实现并行计算。在代码调试过程中我也遇到了诸多问题。例如初期对CUDA函数的使用不熟悉在cudaMalloc、cudaMemcpy等设备内存操作函数的调用中容易出现内存分配失败、数据拷贝异常等问题对CPU线程与GPU设备的对应关系理解不透彻导致线程分配不合理影响程序运行效率。通过查阅CUDA编程文档、反复调试代码逐步掌握了设备内存的分配与释放、数据在主机与设备间的传输方法以及CPU线程与GPU设备的协同工作逻辑也深刻认识到GPU并行编程不仅需要掌握语法规则更要理解其底层的硬件架构与任务调度机制。实验中通过程序运行结果我清晰看到了CPU与GPU的配置信息以及并行计算的执行效果。程序通过检测可用的CUDA设备数量创建对应数量的CPU线程每个线程控制一个GPU设备处理对应的数据段最终完成数组元素的增量计算并验证结果这让我直观感受到GPU并行计算的高效性——相较于CPU单线程处理GPU通过多线程并行能大幅提升数据处理速度尤其适用于大规模数据运算场景。本次实验不仅让我掌握了GPU环境配置、CUDA程序编写的基础方法更让我深刻理解了GPU并行计算的核心原理与优势也认识到自身的不足对CUDA编程的深入应用还不够熟练对GPU性能调优的方法了解较少。通过本次实验我也明白并行计算技术的学习离不开理论与实践的结合只有多动手、多调试才能真正掌握其精髓。此次GPU并行计算实验为我后续学习更复杂的并行计算技术奠定了坚实基础。在未来的学习中我将进一步深入研究CUDA编程探索GPU与CPU协同并行的优化方法不断提升自身的编程能力与专业素养更好地掌握高性能计算领域的相关技术为后续的专业学习与实践积累更多经验。

相关新闻