【问题标题】:How many copies of a global variable declared inside an opencl kernel function is maintained in the global address space在全局地址空间中维护了多少个在 opencl 内核函数中声明的全局变量的副本
【发布时间】:2013-02-08 18:26:20
【问题描述】:

我是 Opencl 编程的新手。为了更好地学习opencl,在阅读了一些教程之后,我开始开发一个简单的模式匹配内核函数。但我有一些疑问:

首先,我在内核函数中声明了全局变量。这是否意味着每个工作项共享每个变量的一个副本?

其次,我如何使用标准 C 库,尤其是。 “字符串.h”。

   __kernel void matchPatterns_V1(__global char *strings, __global char *patterns, __global int *matchCount,
                            int strCount, int strLength, int patCount, int patLength) {


    int id = get_global_id(0);
    int rowIndex = id*strLength;
    int i, matches = 0;     

    __global char *pos = strings;
    __global char *temp = strings;
    __global char *pat = patterns;

    for(i = 0; i < patCount; i++)
    {
            temp = &strings[rowIndex];      
            pat = &patterns[i*patLength];
            while(pos != '\0') {
                    pos = StrStr(temp, pat);
                    if(pos != '\0') {
                            matches++;
                            temp = pos + patLength;
                    }
            }
    }
    matchCount[id] = matches;
    }

总而言之,每个工作项是否都有自己的变量“pos”、“temp”和“pat”的副本?

我们非常感谢任何有关学习 Opencl 的建议,包括对最佳书籍/教程网站的建议。

【问题讨论】:

    标签: parallel-processing opencl


    【解决方案1】:

    不,它在全局内存空间中,因此通常每个内核调用都有一个副本,供所有工作项共享。如果你不能保证每个工作组在全局内存中都有自己独特的“项目”,那么写入全局内存是很危险的——或者更一般地说,你的内核中没有两个工作项目会同时写入内存中的同一位置)因为会有竞争条件。

    如果你只是从那些全局内存变量中读取数据,当然没关系。

    您也不能在内核中声明__global 变量,因为它们只能是内核参数。如果您尝试这样做,您将从 OpenCL 编译器获得以下信息:

    error: global variables cannot be allocated inside kernel code
    

    出于充分的理由,除非技术上不可能:全局变量根本没有任何作用......我什至能想到的唯一可能的原因是工作项之间的通信,这将是一种疯狂的设计模式。


    至于您的问题,在 cmets 中,请参阅 OpenCL 规范中的这个 sn-p,第 6.5 节:

    // declares a pointer p in the __private address space that
    // points to an int object in address space __global
    __global int *p;
    

    因此,与指针类型相关的内存空间表示它们指向的变量的内存空间,而不是指针本身,它们始终为__private(即每个工作项)。


    您不能在 OpenCL 中使用标准 C 库中的字符串操作函数,但如果您愿意,您可以重新编码它们以在 GPU 上使用(其中大部分很难实现)。

    【讨论】:

    • 感谢您的回复。只要变量是指针类型,就允许在内核中声明 __global 变量
    • @khalil 是的,当然,在这种情况下,它不是具有 __global 属性的指针,而是指向的变量(就像 int8_t *ptr 是指向 C 中的 8 位整数的指针,不是 8 位指针)所以你并没有真正分配任何东西。
    • 如果是这样,这是否意味着像 __global *temp 这样的内核声明对于每个工作项都是唯一的?就像 C 函数中的局部变量声明一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    相关资源
    最近更新 更多