不同内存空间中的OpenCL结构声明

不同内存空间中的OpenCL结构声明,opencl,gpgpu,gpu,Opencl,Gpgpu,Gpu,在OpenCL中,以下结构声明之间的结果和差异是什么。如果它们是非法的,为什么 struct gr_array { int ndims; __global m_integer* dim_size; __global m_real* data; }; typedef struct gr_array g_real_array; struct lr_array { int ndims; __local m_integer* dim_size; __lo

在OpenCL中,以下结构声明之间的结果和差异是什么。如果它们是非法的,为什么

struct gr_array
{
    int ndims;
    __global m_integer* dim_size;
    __global m_real* data;
};
typedef struct gr_array g_real_array;

struct lr_array
{
    int ndims;
    __local m_integer* dim_size;
    __local m_real* data;
};
typedef struct lr_array l_real_array;

__ kernel temp(...){

        __local g_real_array A;
        g_real_array B;

        __local l_real_array C;
        l_real_array D;

}
我的问题是结构将分配到哪里(以及成员)?谁可以访问它们?这是不是一个好的做法

编辑

这个怎么样

struct r_array
    {
       __local int ndims;
    };

typedef struct r_array real_array;

__ kernel temp(...){

        __local real_array A;
        real_array B;

}

如果某个工作项修改了结构B中的ndims,该更改对工作组中的其他工作项可见吗?

它可能不会工作,因为当前的GPU-s对于OpenCL内核和普通程序有不同的内存空间。您必须进行显式调用才能在两个空间之间传输数据,这通常是程序的瓶颈(因为PCI-X图形卡的带宽非常低)。

我已将您的代码重写为有效的CL,或者至少是将编译的CL。在这里:

typedef struct gr_array {
    int ndims;
    global int* dim_size;
    global float* data;
} g_float_array;

typedef struct lr_array {
    int ndims;
    local int* dim_size;
    local float* data;
} l_float_array;

kernel void temp() {
    local g_float_array A;
    g_float_array B;

    local l_float_array C;
    l_float_array D;
}
一个接一个,这是如何分解的:

  • A在局部空间中。它是一个由一个int和两个指针组成的结构。这些指针指向全局空间中的数据,但它们本身是在局部空间中分配的

  • B在私人空间;这是一个自动变量。它由一个int和两个指向全局内存中的内容的指针组成

  • C在局部空间中。它包含一个int和两个指向本地空间中内容的指针

  • D、 在这一点上你大概可以猜到。它在私有空间中,包含一个int和两个指向本地空间中内容的指针

我不能说这两种方法对你的问题是否更可取,因为你还没有描述你的目标

编辑:我意识到我没有回答你问题的第二部分——谁可以访问结构字段

您可以访问变量范围内的任何位置的字段。我猜您认为在g_float_数组中标记为全局的字段位于全局空间(l_float_数组的局部空间)。但他们只是指向全球(或局部)空间的东西

所以,你可以这样使用它们:

kernel void temp(
            global float* data, global int* global_size,
            local float* data_local, local int* local_size,
            int num) 
{
    local g_float_array A;
    g_float_array B;

    local l_float_array C;
    l_float_array D;

    A.ndims = B.ndims = C.ndims = D.ndims = num;

    A.data = B.data = data;
    A.dim_size = B.dim_size = global_size;

    C.data = D.data = data_local;
    C.dim_size = D.dim_size = local_size;
}
顺便说一句,如果你在运行Lion的Mac电脑上破解CL,你可以使用“离线”CL编译器编译.CL文件,这使得实验这类东西更容易一些。它位于这里:

/System/Library/Frameworks/OpenCL.framework/Libraries/openclc

有一些示例代码。

我想你误解了我的意思,结构都在OpenCL代码(.cl文件或内核文件)中。例如,B工作得很好。我可以将一个数组(以及数组信息)从主机(在全局中分配)附加到内核,并在内核中重建它。然后我可以随心所欲地使用它。我只是对A、C和D感兴趣。谢谢你的回复。因此,如果我在struct C中理解正确,如果变量ndims被一个线程修改,那么工作组中的所有线程都可以看到更改。正确的?我补充了一个问题。你能看一下吗?关于编译器,实际上我已经写了一个小的“编译器”,它可以测试编译OpenCL源代码,并读回和构建二进制文件来检查一切是否正常。我的问题是代码的实际含义。是的,因为C在本地内存空间中,所以它由工作组中的所有工作项共享。对C的任何更改都将对所有这些项目可见,但有关在工作组内同步的常规规则适用。对于延迟,很抱歉,但我已经给了您赢得的“接受答案”。