为什么程序(全局)范围变量必须是__constant? [英] Why program (global) scope variables must be __constant?

查看:174
本文介绍了为什么程序(全局)范围变量必须是__constant?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是OpenCL的新手,真的被这个限制所困惑。例如,如果我想编写一个LCG,我必须使状态字可以修改为 rand() srand() code>。在ANSI C中,我会用类似的方法做到这一点:

  / * ANSI C * / 
static unsigned long _holdrand = 1; / *全球! * /

unsigned long rand(){
_holdrand = _holdrand * 214013L + 2531011L;
return(_holdrand>> 16)& 0x7FFF的;
}
void srand(unsigned long seed){
_holdrand = seed;
}

但是OpenCL限制所有全局范围变量< __ constant 。我可以将 _holdrand 移到函数作用域中,并将它的指针移出该函数。

  / * OpenCL C * / 
uint * holdrand(){
__private static uint _holdrand = 1;
return& _holdrand;


uint rand(){
* holdrand()= * holdrand()* 214013L + 2531011L;
return(* holdrand()>> 16)& 0x7FFF的;
}
void srand(uint seed){
* holdrand()= seed;
}

它工作正常,我不知道这是否是一个好的解决方案。这个限制是无稽之谈,我只是通过添加更奇怪的代码来避免它。

  __ private uint _holdrand = 1; 
/ *它应该是同样的东西......为什么这是不允许的? * /

由于静态返回指针的行为方式与ANSI C中的全局范围变量方法,我无法理解限制的含义。有人能解释为什么吗?我错过了什么吗?在这个例子中,我应该如何使 _holdrand 可以在两个不同的函数中修改?

解决方案

每个NDRange(通常)都有数千个工作项目(WI)。想象一下,如果512个线程正在读取/写入相同的变量,您可以实现什么样的性能。这就是为什么你有4个地址空间:每个WI >

  • __ local 适用于工作组内的所有工作小组
  • __ global 用于全部只读变量的

  • __ constant
    >

    如果您的 rand()& srand()函数是WI特有的,您应该使用私有内存。另一种方法是在全局地址空间中使用所需的变量。但在这种情况下,请注意比赛条件。



    OpenCL可以在各种设备上运行,这就是为什么一些限制看起来太强大。 b $ b

    I am new to OpenCL and really confused by this restriction. For example, if I want to write a LCG, I have to make the state word be modifiable to both rand() and srand(). In ANSI C, I will do that with something like:

    /* ANSI C */
    static unsigned long _holdrand = 1; /* Global! */
    
    unsigned long rand(){
        _holdrand = _holdrand * 214013L + 2531011L;
        return (_holdrand >> 16) & 0x7FFF; 
    }
    void srand( unsigned long seed ){
        _holdrand = seed;
    }
    

    But OpenCL restrict all global scope variables being __constant. I could move _holdrand into function scope, and return it's pointer out of that function.

    /* OpenCL C */
    uint* holdrand(){
        __private static uint _holdrand = 1;
        return &_holdrand;
    }
    
    uint rand(){
        *holdrand() = *holdrand() * 214013L + 2531011L;
        return (*holdrand() >> 16) & 0x7FFF; 
    }
    void srand( uint seed ){
        *holdrand() = seed;
    }
    

    It works fine and I don't know if this is a good solution. The restriction made nonsense, I just avoided it by adding more weird code.

    __private uint _holdrand = 1;
    /* It should be the same thing... Why this is not allowed? */
    

    Since the return-a-pointer-of-static manner will behave exactly the same as the global scope variable approach in ANSI C, I couldn't understand what the restriction meaning for. Could someone explain why? Did I missed something? What should I do to make _holdrand modifiable in two different functions in this example?

    解决方案

    Briefly - OpenCL program lifetime & memory layout is different from C program. In OpenCL, you don't have stack, heap, etc. Constant memory is (usually) very fast & little amount of on-chip memory, IO operations to which has the same order of performance in comparison to register operations. So, it may have limitations for write operations from Work Items.

    In every NDRange (usually) there are thousands of Work Items (WI). Imagine what performance you can achieve if, say, 512 threads are reading/writing same variable. That's why you have 4 address spaces:

    • __private for every WI
    • __local for all WIs inside Work Group
    • __global for all WI within NDRange
    • __constant for global read-only variables

    If your rand() & srand() functions are WI-specific, you should use private memory. An alternative way is to have variables you need in global address space. But in this case be very careful with race conditions.

    OpenCL can be run on the vast variety of devices, that's why some restrictions look too strong.

    这篇关于为什么程序(全局)范围变量必须是__constant?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆