我遇到了一个问题,我以前的数组元素会被新值覆盖。
代码尝试执行的操作
我最初有一个包含100个元素的数组(全部来自正弦函数,这是我的输入)。它本质上充当FIFO缓冲器和计算机,当新输入被推入FIFO时,阵列的平均值。我这样做的原因是因为我正在尝试实现移动平均滤波器。
然而,会发生什么是输出倾向于覆盖以前的值。 例如,如果FIFO缓冲区的第一个元素是1(当前意味着缓冲区的其余部分为0),则位置0的输出数组将具有0.01作为值。下一次,如果下一个输入值为0.9,则索引1处的输出值将为(0.01 + 0.009)。但这是指数0的值也被覆盖到与索引1相同的值。
我决定在java中编写相同的代码,它工作得非常好。如果有人能够找出问题我会非常感激。
kernel void lowpass(__global float *Array, __global float *Output) {
float fifo[100];
int queueIn;
float tempVal;
queueIn = 0;
int idx = get_global_id(0);
Output[idx] = 0;
fifo[idx] = 0;
for(int i = queueIn; i < 3; i++){
fifo[i] = Array[i];
tempVal = (float)0;
for(int j = 0; j < 3; j++){
tempVal = (float) (fifo[j]*(.01) + tempVal);
}
Output[queueIn] = tempVal;
queueIn = queueIn + 1;
}
}
注意我将for循环设置为3以进行调试。从跟踪代码开始,它不应该这样做。但话说回来,我可能会错过一些小事。
**由于调试原因,我已经删除了很多变量,例如queueIn,我只需要让数组不会覆盖以前的值。
cmd
的输出示例Java代码
public static void main(String[] args) {
// TODO Auto-generated method stub
//Input,output and fifo arrays
float [] fifo = new float[100];
float [] input = new float[100];
float [] output = new float[100];
//temporary value to hold computed result
float temp = 0;
//initialize array values to 0
for(int i =0;i<100;i++){
fifo[i] = 0;
input[i] = 0;
output[i] = 0;
}
//I know this produces a constant result, but its just
//proof of concept. this array will have values of .707 throughout it
for(int i =0;i<100;i++){
temp = (float) Math.sin(Math.toRadians(45));
input[i] = temp;
}
int queueIn;
float tempVal;
tempVal=0;
queueIn = 0;
//Insert one value at a time into the fifo buffer (first for loop)
for(int i = queueIn; i < 100; i++){
fifo[i] = input[i];
//reset to 0 so it can reaccumilate
tempVal = 0;
//accumilate the values in the array multiplied by a coefficient one value in
//the array changes every time the first for loop executes.
for(int j = 0; j < 100; j++){
tempVal = (float) (fifo[j]*(0.01) + tempVal);
}
//store the value in the current index of the output array.
output[queueIn] = tempVal;
queueIn = queueIn + 1;
}
//verify results
for(int i =0;i<100;i++){
System.out.println(output[i]);
}
}
答案 0 :(得分:3)
内核的第一部分实现为作为NDRange运行,并且是在为Task完成计算时的主要部分(作为单个工作项运行),因此每个工作项都会覆盖这些值。
根据您的Java实现,NDRange内核实现应该是这样的:
kernel void lowpass(__global float *Array, __global float *Output) {
int idx = get_global_id(0);
float tempVal = 0.0f;
for(int j = 0; j < idx+1; j++){
tempVal += Array[j] * 0.01f;
}
Output[idx] = tempVal;
}