1

我分析了我的 matlab 代码以识别最耗时的函数,它们大多是梯度此文件中的Kron matlab 函数,以便将它们写入 cuda 内核,然后 PTX 并从 matlab 调用它们。任何想法或文章都会很好。也mb的计算似乎是可分离的,这使它们成为分配给不同块的好候选者,这是文件中的代码快照

i2w=g0*aff(i2,a0);
[ix,iy]=grad(i2w);

ix=ix.*region;iy=iy.*region;
ix2=ix.^2;iy2=iy.^2;ixiy=ix.*iy;
it=i1-i2w;

m1=sum(sum(kron(ones(1,limy)',(1-centx:limx-centx).^2).*ix2));
m2=sum(sum(kron((1-centy:limy-centy)',(1-centx:limx-centx)).*ix2));

ps:我最近阅读了有关NVMEX的信息,或者在前面提到的此类代码上对此选项的一些帮助,将不胜感激。

4

1 回答 1

1

这是一个太长的问题,无法在一篇文章中回答,但我会给你两个提示。

如果您依赖此代码的性能足以花费大约 2 周的时间编写和测试 CUDA 代码,让我告诉您我的加速 Matlab 代码的方法:

提示1:

首先以这种方式(在 matlab 中)重写有问题的函数,使其仅使用循环、内存访问和可在 CUDA 手册中找到的基本函数,例如在伪 matlab 中的加法、乘法等-代码

    function result_array = MyFunctionToParallelise(constants,source_arrays)
    for x_idx=xcoords
     for y_idx=ycoords
      local_result=inner_function(x_idx,y_idx,constants,source_arrays(x_idx,y_idx));
      store(local_result to result_array(x_idx,y_idx));
     end
    end

如果您这样做并且您的“inner_function”是可并行的(独立于其他 local_results,并且可以按 x_idx、y_idx 等的任何顺序获得),那么您就在家!

  1. 用 C 写你的“inner_function”(你知道 C 和 MEX,对吗?),并确保它是可编译的,返回正确的结果,并在 mex 文件中使用内部 y_idx 的常规循环和外部 x_idx 循环的 OpenMP 化循环. 如果这样做,您通常会获得 4 倍的加速度!(由于 4 核 CPU 上的 openMP)。不需要工具箱和其他付费的东西 - 默认情况下,您可以在 Matlab 和 MEX 中获得。

  2. 为“inner_function”编写一个 CUDA 启动器。无需商业工具箱。这是简单的部分!只需将“for 循环”替换为线程和块即可。. . . 并将其插入到您以前使用常规功能的 mex 文件中。在此步骤中,预计 C 的 10 倍 - 100 倍加速。

按照这种方法,您将能够在每一个小步骤中调试和验证正确性。根据我的经验,管理缓冲区指针和缓冲区大小的代码中的拼写错误是崩溃和错误结果的主要来源。快速获得错误结果毫无意义!

提示 2:对于一些复杂的函数(如 kron),如果你的输入和输出是固定大小的,则可能使用计算机代数系统获得寄存器级优化、线性、非迭代、非分支代码,如沃尔夫拉姆数学。此类代码在 GPU 上执行速度超快。示例:使用 Mathematica 的公式优化编译器的示例

于 2012-10-28T14:24:07.707 回答