Performance OpenCL/nVidia中的慢速并行内存访问,我错过了什么?

Performance OpenCL/nVidia中的慢速并行内存访问,我错过了什么?,performance,opencl,nvidia,Performance,Opencl,Nvidia,我正在玩OpenCL、Geforce GTX550和Ubuntu14.04的驱动程序版本331.38。让我困惑的是从全局内存复制到本地内存的速度。据我所知,以下代码应该对全局内存进行联合访问: void toLocal(__local float* target, const __global float* source, int count) { const int iterations = (count + get_local_size(0) - 1) / get_local_siz

我正在玩OpenCL、Geforce GTX550和Ubuntu14.04的驱动程序版本331.38。让我困惑的是从全局内存复制到本地内存的速度。据我所知,以下代码应该对全局内存进行联合访问:

void toLocal(__local float* target, const __global float* source, int count) {
    const int iterations = (count + get_local_size(0) - 1) / get_local_size(0);
    for (int i = 0; i < iterations; i++) {
        int idx = i * get_local_size(0) + get_local_id(0);
        if (idx < count)
            target[idx] = source[idx];
    }
}
void toLocal(_本地浮点*目标,常量_全局浮点*源,整数计数){
常量int迭代=(计数+获取局部大小(0)-1)/获取局部大小(0);
对于(int i=0;i
实际上,以下代码(应使用所有线程反复复制同一个浮点)的速度要快得多:

void toLocal(__local float* target, const __global float* source, int count) {
    for (int i = 0; i < count; i++)
        target[i] = source[i];
}
void toLocal(_本地浮点*目标,常量_全局浮点*源,整数计数){
for(int i=0;i
源和目标都直接指向缓冲区的开头,所以我猜它们是正确对齐的。组大小是16乘16,尝试使用所有线程会使代码更加复杂,但不会影响速度。最佳合并组大小为128字节或32个浮点,但据我所知,在compute model 2卡(GTX550)上,仅使用部分或甚至排列元素的代价应该不会太大。将本地内存围栏添加到第一个版本只会使其速度变慢。还有什么我错过的吗


编辑:将组大小更改为32乘32使并行版本的速度大致与顺序16乘16的速度一样快,并使顺序版本稍微慢一些。仍然不是我期望的速度提升。

如果设置
-cl opt disable
构建选项会发生什么?它禁用优化。在第二段代码中,Combiner可能意识到相同的变量被一次又一次地复制,并将其优化为一个副本?根据,对全局内存的访问有很高的延迟(幻灯片9)。确切的数字很难说,因为这段代码所来自的实际内核大部分时间都在做其他事情。实际速度介于19.2毫秒(我的并行拷贝或异步工作组拷贝在32x32上,对于16x16上的循环)到20.8毫秒之间(16x16上的并行复制,32x32上的循环)。全局内存的高延迟正是我将内容复制到本地内存的原因。让我感到困惑的是,为什么将卷积内核复制到本地内存提高的速度如此之小。第一个版本的开销很大。您能否将其修改为更简单,然后重试?类似于(int idx=get_local_id(0))的
for(int idx=get_local_id);idx
。另外,您所说的
组大小[…]32乘32是什么意思?您在这里只使用了一个维度。