Memory OpenCL:如何在JOCL中使用本地内存

Memory OpenCL:如何在JOCL中使用本地内存,memory,opencl,jocl,Memory,Opencl,Jocl,假设我想对大型固定对象执行并行计算,例如固定大型稀疏(有向)图或任何类似类型的对象 为了对这个图或对象进行任何合理的计算,比如图中的随机游动,出于速度原因,将图放入全局内存可能是不可能的 这会留下本地/私有内存。如果我对GPU架构的理解是正确的,那么(只读)访问本地或私有内存之间几乎没有速度差异,对吗?我不愿意将图形复制到私有内存,因为这意味着每个工作单元都必须存储整个图形,这可能会很快消耗GPU的内存(对于非常大的图形,甚至会减少可使用的内核数量和/或使操作系统不稳定) 那么,假设我在本地和私

假设我想对大型固定对象执行并行计算,例如固定大型稀疏(有向)图或任何类似类型的对象

为了对这个图或对象进行任何合理的计算,比如图中的随机游动,出于速度原因,将图放入全局内存可能是不可能的

这会留下本地/私有内存。如果我对GPU架构的理解是正确的,那么(只读)访问本地或私有内存之间几乎没有速度差异,对吗?我不愿意将图形复制到私有内存,因为这意味着每个工作单元都必须存储整个图形,这可能会很快消耗GPU的内存(对于非常大的图形,甚至会减少可使用的内核数量和/或使操作系统不稳定)

那么,假设我在本地和私有的读取速度上是正确的,那么在实践中如何做到这一点呢?例如,如果为了简化,我将图形从减少到
int[],将
int[]减少到
(存储每个有向边的开始和结束),我当然可以使内核看起来像这样

computeMe(__local const int *to, __local const int *from, __global int *result) {
     //...
}
但是我不知道应该如何从JOCL中调用它,因为这里没有给出私有/本地/全局修饰符


本地变量是否会自动写入每个本地工作组的内存?或者这是如何工作的?我根本不清楚应该如何正确地进行内存分配。

您不能从主机传递本地内存参数的值。主机无法读取/写入本地内存。要使用本地内存,您仍然需要将数据作为全局传入,然后在使用它之前从全局复制到本地。只有在多次读取数据时,这才是有益的

恒定记忆呢?如果您的输入数据没有变化,并且不太大,那么将输入数据放入常量内存可能会给您带来相当大的加速。可用的常量内存通常在16K到64K之间

computeMe(__constant int *to, __constant int *from, __global int *result) {
 //...
}
编辑(添加引用):

有关OpenCL中uu本地内存的使用示例,请参阅


对于NVidia硬件,请参阅更多性能详细信息。其中有关于内存类型之间性能差异的更多信息。

您不能从主机传递本地内存参数的值。主机无法读取/写入本地内存。要使用本地内存,您仍然需要将数据作为全局传入,然后在使用它之前从全局复制到本地。只有在多次读取数据时,这才是有益的

恒定记忆呢?如果您的输入数据没有变化,并且不太大,那么将输入数据放入常量内存可能会给您带来相当大的加速。可用的常量内存通常在16K到64K之间

computeMe(__constant int *to, __constant int *from, __global int *result) {
 //...
}
编辑(添加引用):

有关OpenCL中uu本地内存的使用示例,请参阅

对于NVidia硬件,请参阅更多性能详细信息。在这里,有更多关于内存类型之间性能差异的信息。

您写道“出于速度原因,将图形放入全局内存可能是不可能的。”-您没有太多其他选择。我的意思是数据一般都在全局内存中

(作为旁注-在特定情况下,您可以将其重铸为纹理(如果元素格式合适)。此外,nvidia上所谓的“常量”内存针对“广播”类型的操作进行了优化,这意味着所有线程都从同一位置读取,我想情况并非如此。我建议在开始时远离这些类型。)

好的,作为建议,首先尝试简单地使用“全局内存”。 本地内存的“生存期”仅在内核执行期间。只有在多次重复使用同一数据元素时(将其视为明确预加载的缓存),才有理由这样做

此外,本地内存限制在16-48KB左右,因此它只能存储部分数据。尝试将图形分解为适合这些块的子图

在表示中,可以将边(从[]到[])划分为固定大小的组

通用模式是

第一步。从全局复制到本地

您的\u local\u数组[get\u local\u id(0)]=输入\u global\u mem[get\u global\u id(0)]

第二步。确保每个线程都执行操作 屏障(本地mem围栏)

现在,工作项(线程)可以在本地内存中加载的子图上工作

记住,本地mem只包含整个图的有限部分。 如果需要从任何线程访问任意节点,则上述模式将不可用

我建议在不使用本地内存(直接从全局读取)的情况下开始使用该算法进行实验,并确保其正确工作(通常在路上会有一些惊喜)。 稍后,您可以确定哪些数据部分可以存储在本地mem中以加快速度。

您写道:“出于速度原因,将图形放入全局内存可能是不可能的。”-您没有太多其他选择。我的意思是数据一般都在全局内存中

(作为旁注-在特定情况下,您可以将其重铸为纹理(如果元素格式合适)。此外,nvidia上所谓的“常量”内存针对“广播”类型的操作进行了优化,这意味着所有线程都从同一位置读取,我想情况并非如此。我建议在开始时远离这些类型。)

好的,作为建议,首先尝试简单地使用“全局内存”。 本地内存的“生存期”仅在内核执行期间。只有在多次重复使用同一数据元素时(将其视为明确预加载的缓存),才有理由这样做

此外,本地内存限制在16-48KB左右,因此它只能存储部分数据。尝试将图形分解为适合这些块的子图

在你的陈述中,你可以