代码之家  ›  专栏  ›  技术社区  ›  Safron

OpenCL何时使用全局、私有、本地、常量地址空间

  •  10
  • Safron  · 技术社区  · 7 年前

    我试图学习OpenCL,但我很难决定使用哪些地址空间,因为我只找到声明这些地址空间是什么的集合资源,而没有找到它们存在的原因或何时使用它们。资源至少过于分散,因此我希望通过这个问题收集所有这些信息: 什么是所有的地址空间,它们为什么存在,何时使用哪个地址空间,关于内存和性能的优缺点是什么。

    据我所知(可能过于简化),GPU有两种物理类型的内存: ,与实际的处理器相去甚远,速度很慢但相当大,所有工人都可以使用,而且 本地存储器 ,接近实际处理器,速度快但体积小,其他工人无法使用。

    local 限定符确保变量放置在本地内存中,并且 global private constant 限定符。这些的目的是什么?

    the specifications 提及 通用地址空间

    例子: 假设我传递了一个类型数组 long global const 因为它必须对所有工人可用,并且不会改变。为什么我不使用 常数 合格者当通过CPU为这个数组设置缓冲区时,实际上我也可以将数组设置为只读,在我看来,这与声明它是一样的 const 那么,我什么时候为什么要申报 常数 全局常数

    在执行内存密集型任务时,是否最好将阵列复制到内核内的本地阵列?我的猜测是本地内存太小了,但是如果数组的长度只有10呢?阵列什么时候会太大/太小?更一般的情况:什么时候值得将数据从全局内存复制到本地内存?

    const int length 但是我不确定为什么我会省略 除非我见过其他人这么做。毕竟 length

    我希望有经验的人能澄清这一点。这不仅对我来说太棒了,我也希望对其他想获得一些关于GPU内存管理的实用知识的爱好者来说。

    1 回复  |  直到 4 年前
        1
  •  11
  •   DarkZeros    7 年前

    缓存全局内存的一小部分可供所有工作人员看到。如果可以,请使用它,只读。

    全球的: 慢,所有人都能看到,读或写。它是你所有数据的终点,所以访问它总是必要的。

    本地:

    私人: 只对工作者可见的内存,将其视为寄存器。默认情况下,所有未定义的值都是私有的。


    将只用于读取,然后我将声明它为全局常量,因为它必须 所有工人都可以使用,并且不会改变。为什么我不使用 常数限定符?

    constant 合格者它将数据放在恒定内存中(所有工作人员都可以快速访问的只读内存的一小部分)。这由GPU用于将统一传输到所有顶点着色器。

    只是可以将数组设置为只读,在我看来 与声明它为常量相同。那么,我什么时候以及为什么要申报呢

    不完全是这样,当你创建一个只读的缓冲区时,你只是指定给OpenCL,你计划以只读的方式使用它,所以它可以在后面进行优化,但实际上你可以从内核写入它。 global const 它只是开发人员的一种保护措施,所以您不会意外地对其进行写入,它会在编译时出错。

    在执行内存密集型任务时,是否最好将阵列复制到内核内的本地阵列?我的猜测是本地内存太小了,但是如果数组的长度只有10呢?阵列什么时候会太大/太小?更一般的情况:什么时候值得将数据从全局内存复制到本地内存?

    此处有用:

    Worker0 -> Reads 0,1,2,3
    Worker1 -> Reads 0,1,2,3
    Worker2 -> Reads 0,1,2,3
    Worker3 -> Reads 0,1,2,3
    

    Worker0 -> Reads 0
    Worker1 -> Reads 1
    Worker2 -> Reads 2
    Worker3 -> Reads 3
    

    假设我也想传递这个数组的长度,然后我会添加 const int length到我的内核参数,但我不确定为什么 将省略全局限定符,除非因为我看到了其他 人们这样做。毕竟,长度必须适合所有工人。如果 我真的不知道那意味着什么。

    当您没有在内核参数中指定限定符时,它通常默认为 ,这就是您希望所有工人都能快速访问这些小元素的原因。