OpenCL Blocks语法

为了方便讲述设备队列中的内容,现在我们就对块语法做简要的说明。从OpenCL 2.0开始支持clang Block语法。Block是对C语言的扩展,用来实现闭包的特性。类似于其他语言脚本或者编程语言中的闭包或者是Lambda表示式,可能第一眼看上去有点诡异。我们先来看一个例子如下图所示。

块语句使用示意图

对于如上代码,按照函数调用方式调用块对象变量即可:

int result = myBlock(4) ; //result=28

在例子中,声明myBlock为一个变量,用“^”符号来表示这是一个block。block的输入和返回值为整型数据。block文字开始也用“^”标示,block的实体包含在{}中,并在最后使用“;”来表示结束。通过block文字表达来生成blocks参考。例如:

^ void (void){printf ("hello world\n")};

上述block文字表达生成了一个没有参数也没有返回值的block引用。

上述block文字表达生成了一个没有参数也没有返回值的block引用。
通过上述例子以及图4-10,我们看到对一个block变量的声明非常简单,其语法形式与函数指针几乎一模一样,就是将*变成^。所以用形式化的方法来写就是——〈block返回类型〉(^〈block变量标识符〉)(〈block形参列表〉)。而定义一个block实体的形式化方法为——^(〈block返回类型〉)(〈block实参列表〉){〈block实现的语句块〉}。

而当返回类型为空时,block实体可写为:^(〈实参列表〉){〈block语句块〉}。如果连实际参数列表也为空,则可更简单地写为:^{〈block语句块〉}。
block变量存储的是blocks实体的引用,下面是一些合法的块声明:

//返回void类型,参数也是void类型的块
void (^blockReturningVoidWithVoidArgument)( void );
//返回int类型,两个输入参数分别是int和char类型的块
int (^blockReturningIntWithIntAndCharArguments)( int , char );

下面的例子中,展示了如何在内核函数中使用block调用其他内核函数:

kernel DeviceEnqueueKernelA(global int *input, global int *out)
{
……
}
kernel void CallDeviceEnqueue(global int *input, global int *out)
{
    ndrange_t ndrange;
    ……
    void (^device_enqueue)(void) =
                                  ^ { DeviceEnqueueKernelA (input, out);};
    enqueue_kernel(get_default_queue(), ndrange, device_enqueue);
    ……
}

关于blocks的更多用法,有兴趣的可以参考OpenCL 2.0 C语言官方编程手册。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程