matlab CUDA 内核中二维数组的操作

2023-12-04

假设我有以下序列号C:

int add(int* a, int* b, int n)
{
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {
            a[i][j]+=b[i][j];
        }
    }

    return 0;
}

我认为并行化的最佳方法是认识到这是一个 2D 问题并按照以下方式使用 2D 线程块CUDA 内核 - 嵌套 for 循环

考虑到这一点,我开始像这样编写我的 cuda 内核:

__global__ void calc(int **A, int **B, int n)
{

    int i= blockIdx.x * blockDim.x + threadIdx.x;
    int j= blockIdx.y * blockDim.y + threadIdx.y;


    if (i>=n || j>=n)
        return;

    A[i][j]+=B[i][j];


}

nvcc 告诉我:

./addm.cu(13): Warning: Cannot tell what pointer points to, assuming global memory space
./addm.cu(13): Warning: Cannot tell what pointer points to, assuming global memory space
./addm.cu(13): Warning: Cannot tell what pointer points to, assuming global memory space  

1)我的哲学是正确的吗? 2)我想我理解块,线程等,但我不明白是什么

    int i= blockIdx.x * blockDim.x + threadIdx.x;
    int j= blockIdx.y * blockDim.y + threadIdx.y;

does

3)这是否是在 2D 数组上执行操作的最有效/最快的方法?即不仅仅是矩阵加法,它可以是任何“逐个元素”运算。

4)我可以从matlab中调用它吗?通常当原型是以下形式时它会很奇怪type** var

多谢你们


您收到的编译器警告来自以下事实:在较旧的 GPU 上,内存结构不是“扁平”的。编译器无法知道内核正在工作的指针数组所保存的地址是什么内存空间。因此它警告您,它假设该操作正在全局内存中执行。如果您编译 Fermi 卡(sm_20 或 sm_21 架构)的代码,您将不会看到该警告,因为这些卡上的内存模型是“平坦”的,并且硬件在运行时可以正确解释指针。编译器不需要在编译时处理它。

回答您的每个问题:

  1. 是的。和不。总体想法大约 90% 正确,但有几个实施问题将从下面的答案中变得显而易见。

  2. CUDA C 具有内置变量,允许每个线程确定其在其运行的执行网格中的“坐标”,以及每个块和网格本身的尺寸。threadIdx.{xyz}提供块内的线程坐标,以及blockIdx.{xyz}块与网格的坐标。blockDim.{xyz} and gridDim.{xyz}分别提供块和网格的尺寸(注意并非所有硬件都支持 3D 网格)。 CUDA用途栏目主要顺序用于对每个块内的线程以及每个网格内的块进行编号。您正在查询的计算正在计算等价的{i,j}使用线程和块坐标以及块大小在 2D 网格中进行坐标。 CUDA 编程指南的“编程模型”一章的前几页对此进行了详细讨论。

  3. 不,我这么说有两个原因。

    首先,在 CUDA 中使用指针数组进行内存访问并不是一个好主意。两级指针间接寻址极大地增加了获取数据的延迟损失。与现代 CPU 架构相比,典型 GPU 架构的主要区别在于内存系统。 GPU 具有惊人的高峰值内存带宽,但访问延迟非常高,而 CPU 的设计目标是最小延迟。所以必须阅读和间接两个指针从内存中获取值会带来很大的性能损失。将二维数组或矩阵存储在线性存储器中。这就是 BLAS、LAPACK 和 Matlab 所做的事情。

    其次,代码中的每个线程都为每个“生产性”整数运算(加法)执行四个整数算术运算的设置开销(索引计算)。有一些策略可以减少这种情况,通常涉及让每个线程处理多个数组元素。

    如果我要为该操作编写一个内核,我会执行类似于答案底部的代码的操作。这使用线性存储器和1D grid。适当数量的线程可以正确占用 GPU 处理整个输入数组,每个线程处理许多输入。

  4. 不会。正如我之前在回答中提到的,Matlab 使用线性内存来存储矩阵,而不是指针数组。这与您的内核代码期望的布局不匹配。

示例代码:

__global__ void calc(int *A, int *B, int N)
{

    int i = blockIdx.x * blockDim.x + threadIdx.x;
    int s = blockDim.x * gridDim.x;

    for( ; i<N; i+=s) {
        A[i] += B[i];
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

matlab CUDA 内核中二维数组的操作 的相关文章

  • 同时重新排序和旋转图像的高效方法

    为了快速加载 jpeg 我为turbojpeg 实现了一个 mex wrapper 以有效地将 大 jpeg 读入 MATLAB 对于 4000x3000px 的图像 实际解码只需要大约 120 毫秒 而不是 5 毫秒 然而 像素顺序是 R
  • MATLAB 图中轴标签与轴之间的距离

    我正在使用 MATLAB 绘制一些数据 我想调整轴标签与轴本身之间的距离 但是 只需向标签的 位置 属性添加一点即可使标签移出图窗窗口 是否有 保证金 属性或类似的东西 在上图中 我想增加数字和标签 Time s 之间的距离 同时自动扩展数
  • cudaMemcpy() 与 cudaMemcpyFromSymbol()

    我试图找出原因cudaMemcpyFromSymbol 存在 似乎 symbol func 可以做的所有事情 nonSymbol cmd 也可以做 symbol func 似乎可以轻松移动数组或索引的一部分 但这也可以使用 nonSymbo
  • 如何使用 CUDA/Thrust 对两个数组/向量根据其中一个数组中的值进行排序

    这是一个关于编程的概念问题 总而言之 我有两个数组 向量 我需要对一个数组 向量进行排序 并将更改传播到另一个数组 向量中 这样 如果我对 arrayOne 进行排序 则对于排序中的每个交换 arrayTwo 也会发生同样的情况 现在 我知
  • 如何为 CUDA 内核选择网格和块尺寸?

    这是一个关于如何确定CUDA网格 块和线程大小的问题 这是对已发布问题的附加问题here https stackoverflow com a 5643838 1292251 通过此链接 talonmies 的答案包含一个代码片段 见下文 我
  • Python 或 C 语言中的 Matlab / Octave bwdist()

    有谁知道 Matlab Octave bwdist 函数的 Python 替代品 此函数返回给定矩阵的每个单元格到最近的非零单元格的欧几里得距离 我看到了一个 Octave C 实现 一个纯 Matlab 实现 我想知道是否有人必须用 AN
  • Matlab 一个图上有多个图例 2014b

    我想在一个地块上有多个传说 该解决方案在 2014b 版本之前完美运行 我试图弄清楚如何使用手柄优雅地制作它 但到目前为止还没有成功 欢迎任何想法 2013b 的示例 x 1 50 y1 sin x 2 y2 cos x 2 f figur
  • 如何使用Matlab将数据保存到Excel表格中?

    我想将数据以表格形式保存在 Excel 工作表中 它应该看起来像 Name Age R no Gpa Adnan 24 18 3 55 Ahmad 22 12 3 44 Usman 23 22 3 00 每次当我执行我的文件时类数据 m 下
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I
  • 如何在Matlab中打印带有千位分隔符的整数?

    我想使用逗号作为千位分隔符将数字转换为字符串 就像是 x 120501231 21 str sprintf 0 0f x 但随着效果 str 120 501 231 21 如果内置fprintf sprintf做不到 我想可以使用正则表达式
  • Matlab 图像数据的 hist 函数

    我是 Matlab 新手 我想制作自己的函数 与 imhist 显示图像数据的直方图 完成相同的工作 但我对此完全是新手 我不知道如何做开发这样的功能 我开始做一些东西 但它非常不完整 function output args myhist
  • 命令 A(~A) 在 matlab 中的真正作用是什么

    我一直在寻找找到矩阵非零最小值的最有效方法 并在论坛上找到了这个 设数据为矩阵A A A nan minNonZero min A 这是非常短且高效的 至少在代码行数方面 但我不明白当我们这样做时会发生什么 我找不到任何关于此的文档 因为它
  • 内联 PTX 汇编代码强大吗?

    我看到一些代码示例 人们在 C 代码中使用内联 PTX 汇编代码 CUDA工具包中的文档提到PTX很强大 为什么会这样呢 如果我们在 C 代码中使用这样的代码 我们会得到什么好处 内联 PTX 使您可以访问未通过 CUDA 内在函数公开的指
  • 在matlab中不使用for循环检查数组中的成员资格

    我想简化这段代码 使其无需 for 循环即可工作 for i 1 N for j 1 N if ismember j A PID i i TFP i j PID i i end end end 其中A是一个包含一些标签的矩阵 我之前存储的T
  • Matlab:3D 堆积条形图

    我正在尝试创建一个 3D 堆积条形图 如这个问题所示 Matlab 中的 3D 堆叠条形图 https stackoverflow com questions 13156133 3d stacked bars in matlab 5D 然而
  • 将 Matlab 数组移植到 C/C++

    我正在将 matlab 程序移植到 C C 我有几个问题 但最重要的问题之一是 Matlab 将任何维度的数组都视为相同 假设我们有一个这样的函数 function result f A B C result A 2 B C A B and
  • FMINCON 的替代方案

    除了 fmincon 之外还有其他更快 更高效的求解器吗 我正在使用 fmincon 来解决特定问题 但对于中等大小的向量变量来说 我的内存不足 我也没有任何超级计算机或云计算选项可供使用 我知道任何替代解决方案仍然会耗尽内存 但我只是想看
  • 将 kinect RGB 和深度值转换为 XYZ 坐标

    我正在寻找一种简单的方法将 kinect RGB 和深度值转换为 XYZ 坐标 使用 MATLAB 我的目标是一个输入为以下内容的函数 每个点的 RGB 和深度值Kinect相机 并输出 每个点的 x y 和 z 值 RGB 深度 RGB
  • 通过多次合并相同的行向量来构建矩阵

    有没有一个matlab函数可以让我执行以下操作 x 1 2 2 3 然后基于x我想建立矩阵m 1 2 2 3 1 2 2 3 1 2 2 3 1 2 2 3 您正在寻找REPMAT http www mathworks com help t
  • MATLAB - 通过垂直连接子矩阵重新排列矩阵

    我在执行以下任务时遇到问题 假设一个 3x6 矩阵 A 0 2787 0 2948 0 4635 0 8388 0 0627 0 0435 0 6917 0 1185 0 3660 0 1867 0 2383 0 7577 0 6179 0

随机推荐