技术文章和通讯

解决大型几何和GPU计算在MATLAB可视化问题

保罗•皮MathWorks


常常需要规模技术计算问题涉及少量的数据更大的数据集。简单的循环在每个部分的数据可以成为计算瓶颈,特别是如果应用程序必须在实时运行。MATLAB®为加速算法提供了几种方法,包括多核处理器上执行并行计算和gpu。如果你有一个NVDIA GPU可用,一种方法是利用GPU的并行体系结构和吞吐量与并行计算工具箱™。某些类型的问题,特别是在计算几何和可视化,可以非常有效地解决在GPU上。

在本文中,我们将修改一个算法在GPU上运行,然后解决几何问题涉及数以百万计的线条和形状在第二个。我们说明这种方法使用的问题跟踪光线相交的对象。这种类型的问题是出现在各种各样的应用程序,包括场景渲染和医学成像。

这个例子中的代码可用下载

场景渲染的例子

我们的目标是呈现一个场景所点燃的一个有向光源。我们已经创建了一个三角面和绘制一组射线来自角落相交的对象(图1)。利用MATLAB,我们可以确定有多少光线与对象中的每个三角形相交。此信息可以用于计算光的强度的表面,因此,应该如何呈现的光。

GPU_fig1_w.jpg
图1所示。计算光线之间的十字路口和一个三角面。

核心算法落实决定一条直线相交三角形。该算法接受五套输入坐标向量,它返回一个标志,如果线相交的三角形。

阅读的功能,我们发现它只作用于一行,每调用一个三角形。

功能标志= rayTriangleIntersection(起源、方向、p0, p1, p2)

对于我们的应用程序中,我们将需要遍历所有场景中的光线和表面的三角形。自1000年有780个三角形和射线在这个例子中,我们将需要调用这个函数780000倍。随着我们规模更大、更复杂的场景,该算法将成为计算瓶颈。

加速策略

有几种技术我们可以使用加速算法。例如:

  • Vectorizing-modifying函数接受多个行或三角形的一个电话
  • 写一个墨西哥人在C代码函数来遍历数据
  • 将问题分成更小的问题,分配给工人使用并行计算工具
  • 修改算法在GPU并行运行

这些技术包括修改、测试和基准测试代码。选择最好的方法将执行,我们需要了解更多关于这个算法。

首先,我们注意到的计算量比的数据量更大。如果有R射线和T三角,我们需要3 x (R + T)点来描述场景,然而十字路口是RxT计算的数量。

第二,计算在每一个可能的交点是独立和只包含少量的转换逻辑。的问题,需要更多的计算数据,并可以独立执行的计算,是适合GPU的体系结构。

算法采用固定数量的输入在恒定的维度和只返回标量输出,我们可以重新编码算法使用arrayfun然后直接在GPU执行算法。arrayfun是一个MATLAB函数,一个指定的函数适用于一组数组的每个元素。如果一个数组是一个gpuArray在GPU,函数执行。

使功能兼容arrayfun

一个函数可以调用使用arrayfun必须只有标量输入和输出参数。我们扩展原始输入参数列表中的每个三元素向量到每个X, Y, Z坐标。

功能标志= rayTriangleIntersection_gpu(牛,oy, oz,…dx, dy, dz,…p0x、p0y p0z,……p1x、p1y p1z,……p2x、p2y p2z)

然后我们把剩余的算法使用标量值参数。例如,这行代码减去两个三角形的顶点:

e2 = p2-p0;

我们执行减法显式地为每个维度:

e2x = p2x-p0x;e2y = p2y-p0y;e2z = p2z-p0z;

为了避免编码错误,我们可以使用辅助函数来封装操作,比如一个向量叉乘。

q =交叉(d, e2);

现在被写成

[qx, qy,求出]= cross_product (dx, dy, dz, e2x e2y, e2z);

helper函数被定义为在哪里

函数(w1 w2, w3) = cross_product (u1, u2, u3, v1、v2 v3)
w1 v2 = u2 * v3 - u3 *;w2 = u3 * v1 - u1 * v3;w3 v1 = u1 * v2 - u2 *;结束

调用函数gpuArray输入参数

MATLAB的工作区中,我们创造了矩阵A, B和C为顶点的三角形对象维度3 xt,其中T是三角形的数量,和一个包含每个射线的方向向量,矩阵D维度Rx3, R的行数。

执行arrayfunGPU,至少其中一个矩阵必须显式地搬到GPU。

gD =gpuArray(D);

然后,我们调用arrayfun直接通过三角形顶点矩阵的每一列和每一行的方向向量分别。arrayfun将GPU的另一个输入参数数组和扩展的参数单维度与维度的其他输入。在这种情况下,起源是扩展的行数和三角形。三角形是每一行复制,反之亦然。

H =arrayfun(@rayTriangleIntersection_gpu……起源起源(1),(2),(3)起源,…gD (: 1), gD (:, 2), gD (:, 3),…(:1)、B (: 1), C (: 1),…(:,2)、B (:, 2), C (:, 2),…(:,3)B (:, 3), C (:, 3));

一旦我们已经计算出所有的十字路口,我们需要计算每个三角形的十字路口数量。我们可以在GPU上执行这个计算,然后通过表面回MATLAB可视化结果。

numhits =收集(sum (H, 1));

请注意,我们试图限制传递的数据量的GPU。现场的坐标需要复制每一个十字路口。我们可以通过使用repmat在MATLAB矩阵GPU工作区,然后转移矩阵。然而,这种方法涉及到传输更多的数据比如果我们通过GPU,让原始数据arrayfun处理每个交点坐标是如何结合的。

同样的,我们只从GPU检索每个三角形的数量,而不是完整的十字路口。减少传输的数据量可以显著降低GPU计算所花费的时间。

比较的方法

一些练习和重用的辅助函数,它是可能的修改算法在GPU上运行使用arrayfun在相同的时间,它需要一个有经验的MATLAB程序员对代码进行向量化。使用现有的MATLAB代码生成场景和十字路口通过循环计算每一行和三角形,我们找时间处理780000十字路口图1所示从46秒减少到3毫秒!

显然,这是一个重大的改进。我们也应该证明方法扩展到更大的问题,利用GPU是一个更好的选择比其他加速这类问题的策略。图2中的情节比较大场景的执行时间使用我们的GPU的算法时,矢量化版本,墨西哥人使用MATLAB编码器™创建的文件。的函数时间gputimeit被用来估计的平均执行时间不同数量的可能的十字路口。

GPU_fig2_w.jpg
图2。矢量化的性能比较,墨西哥人,GPU的方法更大的问题大小。

如图2所示,GPU的并行化提供了性能优越的相对简单的场景(100000十字路口)和数量级的场景更为复杂。

将这种方法扩展

我们提出了几个大的特点解决几何问题,使其适合GPU使用arrayfun。然后,我们展示了如何修改代码计算算法以最小的数据传输的GPU。算法运行在GPU上的速度快了比使用其他加速度方法在本文中引用。

这种方法可以用来加速其他算法。任何问题,包括计算一个每一个元素的组合数据集之间的相互作用是值得考虑的,因为涉及的数据量小于所需的计算。

常见的操作,比如矩阵乘法和计算快速傅里叶变换有这个属性。许多这些操作实现了GPU的并行计算工具。

这里有两个更多的想法尝试:

  • 计算交叉口的射线和盒子。这种方法经常被用来减少可能的十字路口复杂对象之前,将该算法应用于找到实际的十字路口。
  • 搜索两个时间序列的时间他们最强烈的关联来计算两个序列的一致性。这个函数xcorr在信号处理工具箱™是一个很好的起点。的一个实现xcorr优化运行在GPU上的现在可以当使用并行计算工具。

我们已经看到如何MATLAB算法可以很容易地修改在GPU上运行使用arrayfun方法和并行计算工具。对于涉及大量数据的问题,arrayfun方法可以显著优于向量化和墨西哥人的方法。

关于作者

保罗剥是MathWorks顾问工程师专门从事信号处理、机器学习、代码生成嵌入式硬件。他与MATLAB和Simulink用户开发算法和模金宝app型系统在多个域,并将代码部署到实时的目标。保罗持有统计信号处理来自剑桥大学的博士学位,英国。

2014 - 92206 v00出版

查看相关文章的能力