OpenCL - 被覆盖的数组值

时间:2016-05-16 18:47:59

标签: c arrays 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]);
    }

}

1 个答案:

答案 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;
}