2016-05-16 53 views
0

我遇到了一个问题,我之前的数组元素被新值覆盖。OpenCL - 被覆盖的数组值

什么代码正在尝试做

我本来有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输出

enter image description here

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

你说这工作在java中。你能发布java代码吗?不确定你想要做什么。 –

+0

刚刚发布了代码。主要部分是这样的,我有两个for循环。第一个for循环将一个元素一次插入FIFO循环缓冲区。在添加元素之后,下一个for循环开始执行,并重新计算整个数组的平均值乘以系数。最终目标是为信号实现移动平均滤波器。 – VedhaR

+0

而不是'0.01',我期望'(fifo [j] *(。01)+ tempVal)''1.0/4';'。 – chux

回答

3

内核的第一部分是对正在运行的NDRange与主要部分实现时,将计算任务完成(作为单个工作项目运行),因此每个工作项目都会覆盖这些值。

根据您的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; 
} 
+0

谢谢!它效果很好。有点困惑,你的意思是“实现作为NDRange运行”。 – VedhaR

+1

NDRange意味着运行许多工作项,并且在内核开始时使用了'int idx = get_global_id(0);'这表明内核的NDRange类型。对于单独的工作项目内核,您并不需要它。 – doqtor

+0

那么在没有NDRange类型的情况下编码相同的函数是可能的吗?我尝试删除get_global_id(0),但它仍然执行相同的操作。 – VedhaR