由於opencl在異構系統上進行計算,需要管理並排程多個裝置,就需要在裝置之間內部或外部進行資料互動以及同步。
根據同步的型別,同步分為兩部分:宿主機端同步和裝置端同步。
裝置端同步主要指同乙個核心內不同執行緒之前的同步,主要用於保證資料的一致性。根據工作組的劃分,可以細分為組內同步和全域性同步。
opencl採用寬鬆的同步模型和記憶體一致性模型。通常來說,採用硬體實現能夠最好的實現同步,但是作為乙個跨平台的api,並不能完全實現這些特性。所以opencl的解決方案是讓程式設計師明確的知道當前系統的狀態,新增同步點,從而可以依據這些資訊獲取預期行為。
在x86(cpu)平台上,我們使用同步機制如果條件還未滿足,我們可以使系統進入休眠等待條件滿足。但是gpu上的執行緒與系統層級的執行緒不是乙個概念,gpu的執行緒所占用的資源是固定的,不能釋放的,這也就導致了如果不同的不同work group不能為同乙個資源做同步,因為沒有釋放的概念,所以必然存在死鎖的狀態。所以只能組內同步。
組內同步的機制是barrier
,即屏障,在組內所有的item沒有到達這個barrier之前,所有的item是不想下執行的。
4567
89
item1|item2
||item3
||||5s |4s |3s
|||------------------------------ 所有達到 barrier之後,同時出發
||||||
目前opencl不支援與組內同步類似的全域性同步方式(原因上方已經介紹)。可以通過global fence
以及原子操作來達到目的。
opencl是基於任務並行,主機控制的模型,其中每一項任務都是資料並行的,具體通過使用和裝置關聯的執行緒安全的命令佇列來實現。當然,核心、資料以及其他操作並不是簡單呼叫來進行的,而是通過非同步加入指定的佇列中。
從宿主機角度來看,保證宿主機同步的要點有一下三條:
當然,根據所需要同步的計算裝置的個數,可以分為單裝置同步
和多裝置同步
。
clfinish可以阻塞程式的執行直到命令佇列中的所有命令都執行完成。但是這只是相當於在末尾加上了乙個barrier。在中間加入barrier需要呼叫如下函式:
123 cl_int clenqueuebarrier(cl_command_queue command_queue
)等待事件,即將乙個等待事件加入命令佇列,只有這個等待事件滿足以後,才能執行之後加入的命令,使用的命令如下:
12345
cl_int clenqueuewaitforevents(cl_command_queue command_queue,
cl_uint num_events,
const cl_event* event_list
)從變數定義上很好理解,不再贅述。
我們在進行網路訪問或者進行io讀取的時候是如何進行阻塞與非阻塞的區分的呢,沒錯,往往是傳入乙個標誌。對於opencl也是一樣的,如:
1 clenquereadbuffer(que, cl_truem....)上面這個示例的第二個引數就是指定這個函式是否是同步操作,如果為true,那麼就會阻塞直至拷貝完成,如果為false,在設定完後不等拷貝完成,就會返回。
在之前我們已經了解到,使用事件只能在同乙個上下文中實現同步。那麼在不同的裝置不同的上下文中如何實現同步呢,只剩下了一種方法,cfinish,等待另乙個命令佇列執行完成,之後的命令才能繼續執行。如乙個cpu乙個gpu,兩者需要互相訪問彼此的資料,那麼如何實現同步呢,如果cpu要訪問cpu的資料,必須等待cpu當前的命令佇列執行完成,不再占用記憶體,gpu才能進行訪問。
linux同步機制
一.併發控制 1 自旋鎖 得不到資源,會原地打轉,直到獲得資源為止 定義自旋鎖 spinlock t spin 初始化自旋鎖 spin lock init lock 獲得自旋鎖 spin lock lock 獲得自旋鎖,如果能立即獲得,則馬上返回,否則自旋在那裡,直到該自旋鎖的保持者釋放 spin ...
MySQL 同步機制
innodb沒有使用作業系統同步機制,而是自己封裝,通過spin 自旋 和wait array 等待佇列 的設計提高效能 目前的cpu都支援tas指令。該指令通過讀取乙個位元組或者乙個word,然後和0比較,並且無條件的將其在記憶體中的值設為1,是原子操作。用到swap atomic操作,將記憶體中...
執行緒同步機制
本週主要學習 執行緒同步機制 互斥量 讀寫鎖和條件變數 和簡單程式的實現,對執行緒同步有了進一步認識 內容如下 執行緒的基本概念,相關函式 互斥量 說明 處於標圓形框之上的線段表示相關的執行緒沒有擁有互斥量 處於圓形框中心線之上的線段表示相關的執行緒等待互斥量 處於圓形框中心線之下的線段表示相關的執...