如何从dispatch_apply(GCD)循环写入数组?

时间:2011-07-06 21:21:54

标签: c++ macos concurrency grand-central-dispatch

我编写了使用Runge-Kutta方法计算大量耦合主方程的动力学的代码。代码包含许多for循环,其中每个步骤都是独立的。我打算使用Grand Central Dispatch加速该计划。我的尝试是基于http://www.macresearch.org/cocoa-scientists-xxxi-all-aboard-grand-central找到的一个例子。我的代码和macresearch上的示例都没有在我的机器上编译(MacOSX 10.6.8 Xcode 4.0.2)。所以这是我的代码:

...
    double values[SpaceSize], k1[SpaceSize];    

        for ( int t=1 ; t<Time ; t++ ) {

            dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

            //k1
            for (int k=0 ; k<SpaceSize ; k++ ) values[k]=Concentration[k][t-1];

            dispatch_apply(SpaceSize, queue,
                       ^(size_t k)  {
                           k1[k]=h * derives(values, SpaceSize, k); //<--error      
                                    }
                        );
...

它打破了错误:

  

语义问题:无法参考   具有可变修改的声明   在块内输入

我尝试用向量替换数组(values,k1),但后来又得到了另一条错误消息:

  

语义问题:只读变量是   <不可分配

这就是我被困住的地方,并不知道这些错误消息试图告诉我什么。我花了很长时间搜索并询问是否有人可以提供帮助。我非常感谢提示或更好的解决方法。

2 个答案:

答案 0 :(得分:14)

  

错误:无法引用块

中的数组类型的声明

在块实现下,不允许从块访问C数组。 (我找不到关于它的文档......)

有一个简单的解决方法: - )

double valuesArray[SpaceSize], k1Array[SpaceSize];    
double *values = valuesArray, *k1 = k1Array;

答案 1 :(得分:1)

要存储到捕获的变量中,需要将__block存储说明符添加到其声明中。这应该可以解决您遇到的std::vector问题。

具有可变修改类型的问题使得听起来像是在使用可变长度数组。这些不能在块内引用,因为它们无法可靠地复制到块的上下文中(基本上是自定义C struct类型),并且它们可能会弄乱offsetof - 样式计算时使用上下文。您可以通过使用固定大小的变量(只需使用您需要的最大大小),将数组移动到全局/静态存储,或分配指针以及执行指针算法来自行访问第二维来解决此问题。