主要内容

说明三种方法GPU计算:了曼德尔勃特集合

这个例子展示了如何适应你的MATLAB®代码使用GPU计算了曼德尔勃特集合。

从现有的算法,这个例子展示了如何适应您的代码使用并行计算工具箱™利用GPU硬件在三个方面:

  1. 使用现有的算法,但GPU数据作为输入

  2. 使用arrayfun独立对每个元素执行算法

  3. 使用MATLAB / CUDA接口运行一些现有的CUDA / c++代码

设置

下面的值指定高度放大了曼德尔勃特集合的一部分之间的谷主心形和p / q灯泡了。

1000 x1000电网的部分(X)和虚部(Y)创建这些限制和曼德布洛特算法迭代之间在每个网格的位置。对于这个位置500次迭代足以充分渲染图像。

maxIterations = 500;gridSize = 1000;xlim = [-0.748766713922161, -0.748766707771757];ylim = [0.123640844894862, 0.123640851045266];

在MATLAB了曼德尔勃特集合

下面是一个使用标准的MATLAB实现了曼德尔勃特集合命令在CPU上运行。这是基于提供的代码在克里夫硅藻土与MATLAB实验电子书。

设置复杂的二维网格的值。

t =抽搐;xlim x = linspace (xlim (1), (2), gridSize);ylim y = linspace (ylim (1), (2), gridSize);[xGrid, yGrid] = meshgrid (x, y);z0 = xGrid + 1我* yGrid;

500年的迭代,计算下一个价值点复杂的网格z平方的前一个值和增加它的初始值,z0。计算的迭代的数量的大小z小于或等于2。这个计算是矢量化,这样每一个位置更新。

数= 1(大小(z0));z = z0;n = 0: maxIterations z z =。* z + z0;在= abs (z) < = 2;数=数+内部;结束

情节的自然对数。

数=日志(数);cpuTime = toc (t);无花果= gcf;fig.Position = (200 200 600 600);显示亮度图像(x, y,数);colormap([飞机;flipud(飞机);0 0 0));轴标题(sprintf (“CPU执行:% 1.3 f s”cpuTime));

使用gpuArray

当MATLAB遇到GPU数据、计算数据在GPU上执行。类gpuArray提供GPU版本的许多功能,您可以使用它们来创建数据数组,包括linspace,logspace,meshgrid功能需要。类似地,数组初始化直接在GPU上使用函数

确保你想要的GPU和选择是可用的。

gpu = gpuDevice;disp (gpu。名称+“GPU选择。”)
英伟达RTX A5000 GPU选中。

设置复杂的二维网格值在GPU上。

t =抽搐;xlim x = gpuArray.linspace (xlim (1), (2), gridSize);ylim y = gpuArray.linspace (ylim (1), (2), gridSize);[xGrid, yGrid] = meshgrid (x, y);z0 =复杂(xGrid yGrid);

如上所述,应用曼德布洛特算法为每个网格点。

数= 1(大小(z0),“gpuArray”);z = z0;n = 0: maxIterations z z =。* z + z0;在= abs (z) < = 2;数=数+内部;结束

情节的自然对数。

数=日志(数);数=收集(数);naiveGPUTime = toc (t);显示亮度图像轴(x, y,计数)标题(sprintf (“天真的GPU执行:% 1.3 f s(% 1.1外汇更快)”,naiveGPUTime cpuTime / naiveGPUTime))

Element-wise操作

指出该算法操作同样在输入的每一个元素,我们可以把一个函数中的代码和调用使用arrayfun。这个函数processMandelbrotElement提供一个支持函数结束时这个例子。金宝app为gpuArray输入函数使用arrayfun被编译成原生GPU的代码。

提前中止已引入的功能processMandelbrotElement因为这个函数过程只有一个元素。对于大多数的看法了曼德尔勃特集合大量的元素很早就停止,这可以节省许多处理。的循环也被取代了循环,因为他们通常更有效率。这个函数没有提及的GPU和不使用任何GPU-specific特性。

使用arrayfun使MATLAB打一个电话到GPU并行操作,执行整个计算,而不是成千上万的调用单独GPU-optimized操作(至少6每个迭代)。你第一次打电话arrayfun在GPU上运行一个特定的功能,有一些开销GPU执行时间设置功能。后续调用的arrayfun使用相同的函数可以运行得更快。

设置复杂的二维网格的值。

t =抽搐;xlim x = gpuArray.linspace (xlim (1), (2), gridSize);ylim y = gpuArray.linspace (ylim (1), (2), gridSize);[xGrid, yGrid] = meshgrid (x, y);

使用arrayfun曼德布洛特算法申请每个网格点。

数= arrayfun (@processMandelbrotElement,xGrid、yGrid maxIterations);

情节的自然对数。

数=收集(数);gpuArrayfunTime = toc (t);显示亮度图像轴(x, y,计数)标题(sprintf (“GPU执行使用arrayfun: % 1.3 f s(% 1.1外汇更快)”,gpuArrayfunTime cpuTime / gpuArrayfunTime));

使用CUDA

MATLAB实验性能提高了转换C-Mex函数的基本算法。如果你愿意做一些工作在C / c++中,那么您可以使用并行计算工具箱使用MATLAB调用预先写好的CUDA内核数据。为更多的细节在MATLAB使用CUDA内核,明白了CUDA GPU上或PTX代码运行

CUDA / c++实现元素的处理算法提供的这个例子中,pctdemo_processMandelbrotElement.cu。CUDA的一部分/ c++代码,执行下面曼德布洛特算法给出了一个位置。

__device__ unsigned int doIterations(双const realPart0,双const imagPart0, unsigned int const maxIters){/ /初始化:z = z0双realPart = realPart0;双imagPart = imagPart0;无符号整型数= 0;/ /循环直到逃脱而((数< = maxIters) & & ((realPart * realPart + imagPart * imagPart) < = 4.0)){+ +计数;/ /更新:z = * z + z0;双const oldRealPart = realPart;realPart = realPart * realPart - imagPart * imagPart + realPart0;imagPart = 2.0 * oldRealPart * imagPart + imagPart0;}返回计数;}

编译这个文件到一个并行线程执行(PTX)文件使用mexcuda

mexcuda-ptxpctdemo_processMandelbrotElement.cu
建筑“NVIDIA CUDA编译器”。墨西哥人成功完成。

创建一个parallel.gpu.CUDAKernel对象通过CUDA文件和PTX文件parallel.gpu.CUDAKernel函数。

cudaFilename =“pctdemo_processMandelbrotElement.cu”;ptxFilename =“pctdemo_processMandelbrotElement.ptx”;内核= parallel.gpu.CUDAKernel (ptxFilename cudaFilename);

设置复杂的二维网格的值。

t =抽搐();xlim x = gpuArray.linspace (xlim (1), (2), gridSize);ylim y = gpuArray.linspace (ylim (1), (2), gridSize);[xGrid, yGrid] = meshgrid (x, y);

需要一个GPU线程曼德尔勃特集合的每个位置,分为块的线程。内核表明线程阻塞是多大。计算所需数量的线程阻塞,并设置GridSize财产的内核(有效独立的线程块数量将由GPU)。

numElements =元素个数(xGrid);内核。ThreadBlockSize = (kernel.MaxThreadsPerBlock 1 1);内核。GridSize = [(numElements / kernel.MaxThreadsPerBlock),即:1);

评估内核使用函数宏指令

数= 0(大小(xGrid),“gpuArray”);数=函数宏指令(内核、计数xGrid、yGrid maxIterations, numElements);

情节的自然对数。

数=收集(数);gpuCUDAKernelTime = toc (t);显示亮度图像轴(x, y,计数)标题(sprintf (“CUDAKernel执行:% 1.3 f s(% 1.1外汇更快)”,gpuCUDAKernelTime cpuTime / gpuCUDAKernelTime));

总结

这个例子展示了三种方法的MATLAB算法可以适应利用GPU硬件:

  1. 将输入数据转换成在GPU上使用gpuArray,使得该算法不变。

  2. 使用arrayfun在一个gpuArray输入的每个元素上执行该算法独立输入。

  3. 使用一个parallel.gpu.CUDAKernel一些现有的CUDA / c++代码运行使用MATLAB数据。

标题(曼德尔勃特集合在GPU的)

金宝app支持功能

支持函数金宝appprocessMandelbrotElement计算在复杂的迭代次数值数量(x0, y0)跳跃在复平面上的半径为2的圆。每次迭代需要映射z z = ^ 2 + z0在哪里z0 = x0 + i * y0。函数返回的日志在逃避或迭代计数maxIterations如果这一点不逃跑。

函数数= processMandelbrotElement (x0, y0, maxIterations) z0 =复杂(x0, y0);z = z0;数= 1;(数< = maxIterations) & & (abs (z) < = 2)数=计数+ 1;z = * z + z0;结束数=日志(数);结束

另请参阅

|

相关的话题