基于CUDA的GPU计算PI值

访问【WRITE-BUG数字空间】_[内附完整源码和文档]
基于CUDA的GPU计算PI值。本项目使用CUDA编程模型并行计算PI值,研究GPU与CPU效率的比较,分析不同GPU线程分块对性能的影响。
异构计算试验报告
—实验1:基于CUDA的GPU计算PI值

第一部分:实验环境
OS:Windows 10
CPU:intel® Core™ i7-10510U CPU@mailto:CPU@ 1.80Ghz
GPU:NVIDIA GeForce MX250
编译器: cl :v19.29.30133
nvcc:Cuda compilationn tools, release 11.4, V11.4.120
第二部分:实验内容
使用 CUDA 编程模型并行计算 PI 值,研究 GPU 与 CPU 效率的比较,分析不同 GPU 线程分块对性能的影响
第三部分:实验原理
数学原理为
1 积分求解

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

2 幂级数求解

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

使用 CUDA 编程模型,程序执行过程为
CUDAMALLOC -> CUDAMEMCPY(HTOD) ->KERNEL->CUDAMEMCPY(DTOH)

在执行和函数时指定 <<<grid,block>>> 来控制线程的数量和结构
第四部分:性能分析

define N 迭代次数

1 CPU VS GPU
1.1 单核比较
N = (10001000100)=100M
CPU(thread = 1):4.887(s)
GPU(grid = 1,block=1):用时过长…无法测量
1.2 多核比较
首先要发挥出最大的 CPU 性能,由于机器的 CPU 是逻辑 8 核的,所以理论上开启 8 个线程可以发挥最大性能。所以我写了一个 8 线程并行的程序来计算,同样循环 N=(10001000100)次

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

可以看出新的时间为 0.768s 快了不少
(PS:这里的程序是使用 GCC 编译的,而 CUDA 程序 NVCC 调用的是 MSCV 的编译器,Windows 平台上 NVCC 不支持 GCC,但是结果应该是差不多的)
2 GPU 性能分析
接下来就是找出 GPU 的最高性能了。
首先在 grid = 1 下探究 block 里的线程数对性能的影响。这里可以直接用 nvprof 分析,非常方便。
2.1 grid = (1,1,1) block = (10,1,1)

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

一共用时:34.5556s 线程数:10
可以注意到,在本程序中,主要的时间是消耗在计算上的,由于没有什么要拷贝的内存,所以瓶颈只会出现在计算上
2.2 grid=(1,1,1) block=(100,1,1)

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

一共用时:2.58383s 线程数:100
2.3 grid=(1,1,1) block=(1000,1,1)

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

一共用时:1.543s 线程数:1000
每个 block 的最大线程数限制是 1024,这里就不能再增加 block 了在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里提供一个简单的 OpenCV Python CUDA 实例,它将使用 GPU 加速来进行图像处理。该示例将使用 Canny 边缘检测算法来检测图像中的边缘。 首先,您需要确保您的计算机具有 NVIDIA GPU 并且已安装了 CUDA 工具包。然后,您需要安装 `opencv-python` 和 `opencv-contrib-python` 库。您可以使用以下命令来安装它们: ``` pip install opencv-python pip install opencv-contrib-python ``` 接下来,您需要导入所需的库: ```python import cv2 import numpy as np from numba import cuda ``` 然后,您需要将图像加载到内存中: ```python img = cv2.imread('image.jpg') ``` 接下来,您需要将图像转换为灰度图像: ```python gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ``` 然后,您需要将图像分配到 GPU 上: ```python d_img = cuda.to_device(gray_img) ``` 接下来,您需要定义一个 CUDA 内核函数来执行 Canny 边缘检测算法。以下是一个简单的内核函数示例: ```python @cuda.jit def canny_kernel(d_img, d_edges): x, y = cuda.grid(2) if x > 0 and y > 0 and x < d_img.shape[0]-1 and y < d_img.shape[1]-1: dx = (d_img[x+1, y+1] + 2*d_img[x+1, y] + d_img[x+1, y-1]) - (d_img[x-1, y+1] + 2*d_img[x-1, y] + d_img[x-1, y-1]) dy = (d_img[x-1, y-1] + 2*d_img[x, y-1] + d_img[x+1, y-1]) - (d_img[x-1, y+1] + 2*d_img[x, y+1] + d_img[x+1, y+1]) mag = np.sqrt(dx**2 + dy**2) angle = np.arctan2(dy, dx) if angle < 0: angle += np.pi angle = angle * 180 / np.pi if angle > 22.5 and angle <= 67.5: if mag > d_img[x-1, y-1] and mag > d_img[x+1, y+1]: d_edges[x, y] = mag elif angle > 67.5 and angle <= 112.5: if mag > d_img[x, y-1] and mag > d_img[x, y+1]: d_edges[x, y] = mag elif angle > 112.5 and angle <= 157.5: if mag > d_img[x-1, y+1] and mag > d_img[x+1, y-1]: d_edges[x, y] = mag else: if mag > d_img[x-1, y] and mag > d_img[x+1, y]: d_edges[x, y] = mag ``` 该内核函数接受一个输入图像和一个输出图像,并在 GPU 上执行 Canny 边缘检测算法。然后,您需要定义一个 GPU 线程块和网格来执行内核函数: ```python threads_per_block = (32, 32) blocks_per_grid_x = np.ceil(gray_img.shape[0] / threads_per_block[0]).astype(np.int32) blocks_per_grid_y = np.ceil(gray_img.shape[1] / threads_per_block[1]).astype(np.int32) blocks_per_grid = (blocks_per_grid_x, blocks_per_grid_y) ``` 最后,您可以在 GPU 上调用内核函数: ```python d_edges = cuda.device_array_like(gray_img) canny_kernel[blocks_per_grid, threads_per_block](d_img, d_edges) ``` 最后,您可以将处理后的图像从 GPU 复制回到主机内存中: ```python edges = d_edges.copy_to_host() ``` 您可以使用以下代码保存处理后的图像: ```python cv2.imwrite('edges.jpg', edges) ``` 完成!现在您已经学会了如何使用 OpenCV Python CUDAGPU 上加速图像处理了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值