作者:杜偉
英特爾 線程構建模組 (Intel TBB) 是最為人們熟知的一種 C++ 線程庫,其最新的版本現已更新至 4.2。 與之前的 4.1 版本相比,更新後的版本提供了多個重要的新特性。 一些特性已經在 TBB 4.1 更新中發布出來。
新的同步基元 speculative_spin_mutex 提供了對推測鎖定的支援。 這使得在第 4 代英特爾 酷睿 處理器上使用英特爾(R) 事務性同步擴充 (Intel TSX) 硬體特性成為可能。 只要不出現可能會產生不同於非推測性鎖定的結果的“衝突”,推測互斥鎖在支援硬體事務性記憶體 (如英特爾 TSX) 的處理器上工作時就會允許多個線程擷取同一個鎖。 因此在非競爭性案例中就不會發生序列化。 這樣就能在“短”的關鍵地區上大幅提高效能和可擴充性。 如果不為事務性同步提供硬體支援,推測互斥鎖的作用將與非推測互斥鎖類似,同時很可能會表現出更差的效能。
英特爾 TBB 現在支援準確的異常傳播特性(基於 C++11 exception_ptr)。 藉助 exception_ptr,異常對象可以線上程之間安全地拷貝。 這為多線程環境中的異常處理提供了靈活性。 現在準確的異常傳播在所有平台的預構建庫中都已提供,例如: OS X*、Windows* 和 Linux*。 OS X* 上存在兩種庫: 第一個庫與 gcc 標準庫相關聯 — 預設情況下該庫不支援準確的異常傳播。 為了使用該特性,您應當使用與 libc++ (Clang 中的 C++ 標準庫) 相關聯的第二種庫。 為了使用這些特性,請先建立 Intel TBB 環境然後按照以下方式構建您的應用:
# tbbvars.sh libc++
# clang++ -stdlib=libc++ -std=c++11 concurrent_code.cpp -ltbb
除 concurrent_unordered_set 和 concurrent_unordered_map 容器之外,我們現在提供 concurrent_unordered_multiset 和concurrent_unordered_multimap,基於 Microsoft* PPL 原型。藉助 concurrent_unordered_multiset,您可以多次插入一項,而這在concurrent_unordered_set 中是不可能實現的。 同樣,concurrent_unordered_multimap 允許您使用同一個鍵值插入一個以上的 <鍵,值> 對。 就“多” 容器而言,find 會在帶有一個匹配搜尋鍵的表格中返回第一項(或者 <鍵,值> 對)。
Intel TBB 容器現在可以使用 C++ 11 指定的值列表(初始化程式列表)方便地進行初始化:
1 |
tbb::concurrent_vector<int> v ({1,2,3,4,5} ); |
當前,支援初始化程式列表的容器有以下幾種:
concurrent_vector
concurrent_hash_map
concurrent_unordered_set
concurrent_unordered_multiset
concurrent_unordered_map
concurrent_unordered_multimap
concurrent_priority_queue
可擴充記憶體分配程式為每個線程內的已指派記憶體都提供了快取。 這種做法雖然確保了效能,但通常會增加記憶體的使用率。 儘管該記憶體配置程式盡量避免過度使用記憶體,在複雜的情況下 Intel TBB 4.2 還是會把更多的控制權交給程式設計員: 現在可以通過使用 scalable_allocation_command() 函數清理線程快取,進而達到減少記憶體消耗的目的。 這也有助於大幅提高分配程式的整體效能。
Intel TBB 庫已在多種不同平台上獲得了廣泛的使用。 移動開發人員現在可以在 Linux* 作業系統包中找到適合 Android 的預構建二進位檔案。 Windows Store* 應用的二進位檔案已經被添加到 Windows* 作業系統包中。
原子變數 tbb::atomic<T> 現在在 C++11 中使用時已經具備了建構函式。 這允許程式設計員在聲明時就對它們的值進行初始化,同時正確支援構造運算式。 此時,以下代碼對 gcc 和 Clang 編譯器是有效:
新社區預覽特性允許等待,直到所有背景工作執行緒終止。 在應用程式分解進程時,這種情況可能很有必要,否則 TBB 動態庫可能會從運行時中卸載掉(例如,假如 TBB 是一個外掛程式的一部分)。 如果您想啟用背景工作執行緒等待功能,請按以下方式對 task_scheduler_init 對象進行初始化:
1 |
#define TBB_PREVIEW_WAITING_FOR_WORKERS 1 |
2 |
tbb::task_scheduler_init scheduler_obj (threads, 0, /*wait_workers=*/true); |
關於最新英特爾 TBB 4.2 的網站:商用和開源。下載並開始使用全新功能!