2012-10-23 31 views
0

我想實現OpenCL中豪斯多夫距離和下面的內核構成了它的基礎還是我相信它,因爲我還是要完全實現它。這就是說,我可以得到一些建議,或者有沒有一種方法來優化這個內核?基本上,我怎麼能去掉了其中調用輔助函數內核函數循環.....我如何進一步優化該內核的OpenCL

的OpenCL內核及其助手功能:

void helper(int a_1, __global int* b_1, __global int* c_1){ 
     int i = get_global_id(0); 
     c_1[i] = a_1 - b_1[i]; 
} 

__kernel void test_call(__global int* a,    //input buffer of size [100000, 1] 
         __global int* b,    //input buffer of size [100000, 1] 
         __global int* c){   //output buffer of size [100000, 1] 
     for (int iter = 0 ; iter < 100000 ; iter++){ 
       helper (a[iter], b, c); 
       // once array c is obtained by calling the above function, 
       // it will be used in further processing that will take place inside 
       // this for loop itself 
} 

本質上講,我想在這裏做的是用輸入緩衝區'b'中的每個元素減去輸入緩衝區'a'中的每個元素。複雜性將是O(n )。

順便說一句,這種幼稚的做法本身產生2.5秒內的結果。這需要幾分鐘的時間才能完成執行。

+1

我建議刪除函數調用來幫手,並使其內聯。此外,使用編譯指示展開for循環,讓GPU更有效地利用ILP。 – ahmad

+0

感謝您的意見...... – Yash

回答

3

我猜,你的代碼仍然可以通過使用切片方案改進。 在您當前的實現中,所有工作項都加載緩衝區'a'的所有值。目前他們以非同步的方式進行。通過平鋪方案,您可以更好地使用緩存架構,方法是讓器件僅從片外存儲器加載每個「a」值。

該方案是最好的說明如下:http://software.intel.com/file/24571(PDF文件)。

的瓷磚並行方法可能看起來像下面的僞代碼,你的情況。

forall values of b in parallel { 
    foreach tile q { 
     forall work_items p in work_group in parallel { 
      local[p] = a[q*tile_size + p] 
     } 
     synchronize work items in work group 
     foreach body j in tile q { 
      c[i] = local[j] - b[i]; 
     } 
     synchronize work items in work group 
    } 
} 

的核心思想是,每一個WORK_ITEM可以使用「一」已經被同組加載其他work_items緩衝區的值。然後,'a'的每個條目(理想情況下)只會從內存中獲取一次,並從緩存中獲取tile_size-1次。

+0

感謝您的意見。我會試試這個回來...... :) – Yash

+1

使用高速緩衝存儲器將提高執行時間(至少在GPU上)。您也可以將您的輸入數據視爲向量來利用SIMD指令(並非每個openCL編譯器都會自動向內核化您的內核)。 – dkg

+0

@WarfarA,我做了你的建議,它像一個魅力......謝謝你 – Yash