英特爾 執行緒處理工具和 OpenMP

2021-05-11 03:43:21 字數 2663 閱讀 9120

英特爾® 執行緒處理工具和 openmp

顯式執行緒方法(如,windows* 執行緒或 posix* 執行緒)使用庫呼叫建立、管理並同步執行緒。使用顯式執行緒,需要對幾乎所有受影響的**進行重新構建。openmp* 是編譯指示(pragma)、api 函式,及環境變數的集合,能夠以相對較高的級別將執行緒放入應用中。penmp 編譯指示用於指出**中能夠並行執行的域。相容 openmp 的編譯器可轉換該**,並插入適當的函式呼叫以並行執行這些域。多數情況下,可以保留源**的序列邏輯,編譯時只需忽略 openmp 編譯指示即可輕鬆恢復。

為了更具體地闡述重點,選擇對實施 brute force(力迫)演算法的**進行分析,該**用於找出使用者定義整數範圍內的素數。序列**挑出每個可能的素數(不考慮偶數),將其除以所有小於或等於其平方根的整數。如果有某個測試因數可將其整除,則該數為合數;如果沒有因數能將其整除,則為素數。找出的素數可隨意輸出,但通常需要計算所找出素數的總數。我們知道大於 2 的素數可以分為兩類:其形式分別為 4n+1 與 4n-1。除了計算所找到素數的總數以外,素數相關類(被 4 除后的餘數)的計算也隨之增加。所使用的序列**如下:

#include

#include

main(int argc, char *argv)

if (prime)

}printf("/nprogram done./n %d primes found/n",number_of_primes);

printf("/nnumber of 4n+1 primes found: %d/n",number_of_41primes);

printf("/nnumber of 4n-1 primes found: %d/n",number_of_43primes);

作為 openmp* 程式設計助手的英特爾® 執行緒檢查器對於這樣一小段**,僅有一處邏輯位置能夠插入 openmp 程式設計指示:主計算 for 迴圈。將 for 迴圈起始處**更改為:在預設狀態下,共享所有變數(不包括迴圈疊代變數)。通常,一些執行緒需要特定變數的專用拷貝,以避免資料競跑。在某些情況下,如果對這些變數的訪問是同步的,則能夠更好地實現程式的邏輯。在決定如何對共享變數訪問進行最佳保護之前,我們必須識別需要對哪些變數進行保護。在這種簡短的例項中,我們能夠預計,即使僅有少量 openmp 使用經驗的程式設計師,也只需不超過 30 秒的時間來識別需要保護的變數;在下乙個 30 秒的時間內,就可以得出乙個適當的實施保護方法。然而,假定一段大得多的**,其並行區域擁有成百上千行**,或者**涉及大量不同的函式呼叫,在這些呼叫中引數通過指標或不同的變數名進行引用。 現在,找出潛在的儲存衝突則不那麼容易了。幸運的是,英特爾® 執行緒檢查器可自動識別需要某種形式獨佔訪問的變數。對上文例項**新增編譯指示後,通過英特爾® 執行緒檢查器執行該**,將發現在缺少某種並行形式時,變數 limit、prime、j、number_of_primes、number_of_43primes 以及 number_of_41primes 都會導致儲存衝突。通過檢視源**以及對每個變數的嘗試使用,我們能夠判斷如何最佳地對原始源**進行修改,從而實施所需的變數作用域。

任何在讀取前寫入並行區域中的變數,以及變數值不需要在並行區域外使用的變數,都應設為私有(private)。對於 primefinder* 例項**,limit、prime 和 j 即為這種變數,它們僅在並行區域中作為 workspace(工作間)或臨時變數使用。因此,我們能夠通過使用 openmp 程式設計指示的私有語句為每個執行緒分配拷貝。其餘三個計數器變數需要在並行區域後放置列印的全域性總數,在這種情況下,我們應將它們設為共享變數,但需要在關鍵**段內執行這些計數器的增量。所產生的並行域**如下:

#pragma omp parallel for private (limit, j, prime)

for(i = start; i <= end; i += 2)

if (prime) }}

通過英特爾® 執行緒檢查器執行該**顯示無額外的錯誤診斷。我們已建立了正確的執行緒化**。作為 private 語句的替代方法,可以將受影響的區域性變數放入 for 迴圈,而後進入並行區域。如果這些變數並不在**的其它地方使用,則這種解決方案更為完善。這種替代實施方案的另乙個優勢即,對於變數而言序列**與並行**更加匹配。

除了找出需要保護的變數外,英特爾® 執行緒檢查器還能判斷某個**段是否參與了並行。此外,對於長**段或具有深層呼叫堆疊的**而言,判斷在潛在並行迴圈中是否具有任何的依賴性(dependency)是非常枯燥而耗時的工作。若不具備某種演算法更改消除依賴性,則諸如遞迴變數(迴圈的每次疊代都會增加該變數)或遞推關係(在前乙個迴圈疊代上計算訪問資訊)等依賴性會阻礙正確的並行。英特爾® 執行緒檢查器指出儲存衝突,程式設計師對**進行檢查,從而確認變數的使用構成了迴圈依賴。

利用英特爾® 執行緒檔案器進行效能除錯

當建立了正確的執行緒化**後,應該對該**的效能進行測定。可以輕鬆比較序列與執行緒化**的執行時間。當採用兩個執行緒在雙核系統上執行時,如果執行緒化**執行時間是序列**的一半,則說明已完美地實施了並行性。如果執行緒化**的執行時間與序列**的執行時間接近(甚至超過),則一定是出現了某種問題。是否仍有大段**序列執行?所需的同步是否對執行效能產生了負面影響?每個執行緒的工作數量是否完全平衡?

針對 openmp 的英特爾® 執行緒檔案器用於回答這些問題,並指引程式設計師在**中找出可以進行改進的**,從而實現更好的並行效能。鑑於 openmp 的結構化特性,英特爾® 執行緒分析器能夠為應用假定執行模組,並指出非常明確的效能問題。兩個常見問題即負載不均衡與同步開銷。我們應了解英特爾® 執行緒檔案器如何識別這些問題,並對一些可行的解決方案進行討論。

英特爾構建雲集成編排工具

在討論當中,英特爾發現最為核心的要點在於如何將虛擬機器 容器與裸機全部 作為平等公民 由編排方案進行打理。其理由非常簡單,幾乎所有it部門都需要使用混合型工作負載,或者說沒有哪種單一方案足以獨力支撐起傳統業務環境。通過這套新方案,企業客戶能夠將各類元素匯聚至單一模式當中 包括雲分析 例如hadoop...

AMD笑了!英特爾處理器Spoiler漏洞真沒法

近日有研究機構發現,英特爾的處理器中還存在另乙個令人討厭的投機性執行漏洞,被命名為 spoiler,此事令 amd 更受到市場關注。麻塞諸州伍斯特理工學院及德國呂貝克大學的計算器科學家發表了一篇報告指出,英特爾處理器還有乙個類似於去年 spectre 的 推測執行 speculative execu...

面向機器學習和深度學習的英特爾優化工具和框架

本文介紹了面向機器學習和深度學習的英特爾優化工具和框架,還展示了整合至上述優化工具和框架的英特爾庫 有助於充分利用優化工具和框架,在英特爾 架構上實現最佳效能 這些資訊對初次使用的使用者 資料科學家和機器學習工作人員非常實用,能夠幫助他們快速了解英特爾優化工具和框架。簡介 機器學習 ml 屬於一般意...