2016-05-16 77 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