簡體   English   中英

將OpenMP與Cython結合使用:並行化內部循環

[英]Using openMP with Cython: parallelising an inner loop

(如您所見,我對Python GIL和IN PYTHON(或cython)中的多線程等概念不是很熟悉)

我在Cython中編寫了一個函數,該函數由帶有double for循環的代碼片段組成,其中重復調用函數f。

for i in range(I):
  for j in range(J):
    res=f(A[i],B[j])

我有一台具有4個CPU內核的機器,我想並行化的不是第一個循環,而是第二個循環。 我找到了這個很棒的網站,但它不處理內部循環的情況,也不做詳細介紹。 所以我認為我可以寫:

for i in range(I):
  #In what case can I release the GIL safely ? Is that necessary at all ?
  with nogil, parallel(num_threads=4):
    for j in prange(J,shedule="dynamic"):
      res=f(A[i],B[j])

那行得通嗎? 我是否必須將with nogil放在這兩個循環之外,以免它反復出現在其中,從而釋放並“捕獲”該GIL東西? 有人可以向我解釋編寫此類語句背后的邏輯是什么,以及邏輯是什么,以便使我能夠泛化為未發現的問題。

釋放和重新捕獲GIL會花費時間,而建立並行循環也會花費時間。 因此,通常最好將最外面的循環設為並行循環。 但是,如果您有充分的理由特別希望並行化內部循環,則它可以工作,並且希望與f包含的實際工作相比,其成本應該很小。

釋放GIL會阻止您訪問Python變量和調用Python函數。 鍵入Cython變量, cdef函數和Cython內存視圖可以正常工作。 盡量with nogil:加快速度。 因此,如果可能,請將其放在外部循環周圍,但如果不可能,則可以在其中顯示出來。

有必要釋放到GIL進行prange循環。 如有必要,您可以在循環內部( with gil )將其回收,但是嘗試僅在循環的一小部分並且僅在需要時才這樣做(需要GIL的代碼不能與需要GIL的其他代碼並行運行) 。

對於並行代碼,行res=f(A[i],B[j])有點奇怪,因為僅會保存來自最后一個循環的res 通常,您會寫入數組的元素(例如res[i,j]=f(A[i],B[j]) )。 但是,這樣做可能有充分的理由,就像您展示的那樣...

如果您嘗試執行需要GIL的操作,Cython通常會警告您,因此最好嘗試一下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM