以下是内核的代码:
"__kernel void CalculateLWMA( \r\n"
"int rates_total, \r\n"
"int prev_calculated, \r\n"
"int begin, \r\n"
"int InpMAPeriod, \r\n"
"__global double *price, \r\n"
"__global double *ExtLineBuffer \r\n"
") \r\n"
"{ \r\n"
"int i,limit; \r\n"
"static int weightsum; \r\n"
"double sum; \r\n"
"if(prev_calculated==0) \r\n"
"{ \r\n"
"weightsum=0; \r\n"
"limit=InpMAPeriod+begin; \r\n"
"for(i=0;i<limit;i++) ExtLineBuffer[i]=0.0; \r\n"
"double firstValue=0; \r\n"
"for(i=begin;i<limit;i++) \r\n"
"{ \r\n"
"int k=i-begin+1; \r\n"
"weightsum+=k; \r\n"
"firstValue+=k*price[i]; \r\n"
"} \r\n"
"firstValue/=(double)weightsum; \r\n"
"ExtLineBuffer[limit-1]=firstValue; \r\n"
"} \r\n"
"else limit=prev_calculated-1; \r\n"
"for(i=limit;i<rates_total;i++) \r\n"
"{ \r\n"
"sum=0; \r\n"
"for(int j=0;j<InpMAPeriod;j++) sum+=(InpMAPeriod-j)*price[i-j];\r\n"
"ExtLineBuffer[i]=sum/weightsum; \r\n"
"} \r\n"
"}
正如人们可以看到一行:"static int weightsum; \r\n"
我发出以下错误:
error: variables in function scope cannot be declared static
请告诉我,OpenCL内核程序函数中static
的替换是什么?
答案 0 :(得分:1)
我已经对你的代码有了更好的了解,并注意到你对静态变量的使用无论如何都是不正确的,因为weightsum+=k
不是原子的或同步的,即使你有障碍,那里将是并发读取&amp;从不同的工作项目写。你不能在OpenCL中做到这一点。全局变量需要保持不变。
另一件事是你没有接到get_global_id(0)
或类似的电话,这是一个大红旗 - 所有你的工作项目将运行完全相同的代码,或者你和只有一个工作项目。前者意味着您大规模地丢弃计算结果,后者意味着您实际上并未使用任何并行性。在这两种情况下,您的代码都会很慢。这确实意味着weightsum
实际上并不需要是静态的。
如果您想要可变的全局内存,则必须将其作为缓冲区传递。请注意,如果多个工作项需要写入该缓冲区中的相同内存字(或者如果一个写入而其他内容读取),则需要使用全局屏障或原子。更好的方法是使用减少 - 搜索例如&#34; OpenCL并行减少&#34;应该把你带到某个地方。从本质上讲,每个工作项目将尽可能多地单独完成工作,然后工作项目将合作以分层结合其结果。这通常具有O(log(N))的复杂性,而不是原子使用原子的O(N)。