2013-11-21 39 views
1

是否有我可以讀取,修改或默認比較原子的類型? 或者我應該爲所有操作顯式使用所有類型的原子操作?原子指令和原子類型

+0

@Damon我認爲你應該把它作爲答案 – Slava

+0

'std :: atomic '是一種你總是自動讀取和修改的類型(準確地說,轉換爲'T'自動執行原子加載,並從'T'執行一個原子存儲)。我不確定你的意思是「比較原子」。 –

回答

1

是的,你應該總是如果你需要原子性,使用原子類型或原子操作。沒有什麼不同。

形式上,沒有非原子類型默認提供任何類型的原子訪問。實際上,對於當前的CPU,任何內置類型都可以以原子方式讀取和寫入(但不能修改)。但是,這不是你有保證的東西,絕對不是你應該依賴的東西。這僅僅是一個實現細節。
當前CPU上的所有讀取和寫入均通過緩存。只有完整的緩存行(通常大約64-128字節)可以從主內存中讀取或寫回,並且緩存行是最大內置類型大小的倍數。這意味着如果一個類型正確對齊,它必然包含在單個緩存行中,這會自動使其讀寫成原子。但是,修改值是一個讀取 - 修改 - 寫入操作,這意味着即使每個步驟都是原子的,整個操作不是。

有不只是能夠讀取原子(或修改)的值更原子性,例如有您可能需要正確排序保證。即使讀取和寫入是原子性的,如果不按照預期的順序通過不同的處理器看到修改,代碼將無法正常工作。編譯器和CPU(在一些合理的限制內)允許重新排序指令,包括加載和存儲。但是,這可能意味着您的代碼無法正確執行。因此

原子操作有一個「內存模型」與他們有聯繫,它允許你提供什麼的之前發生,保證你的線程之間和相關或不相關的數據之間需要更多的信息。請參閱GCC Wiki以瞭解每種模式的詳細說明。
默認情況下,原子操作選擇順序一致模式,這是最嚴格的限制是最安全的模式。如果你知道你不需要某些保證,你可以選擇一個不同的模型,這可能(或者可能不會),這取決於體系結構)會導致生成更高性能的代碼。
與內存模式的好處是,他們抽象的實現細節,建築pecularities和成decribes你的算法要求,並保證這些要求得到滿足形式編譯巫術。

通常情況下,編譯器就可以正常使用非原子機器指令,仍然保證您的要求得到滿足(這可能會失去一個或另一個重新排序)。這取決於目標硬件如何工作的實際細節以及您需要什麼保證。
總而言之,利用原子能和內存模型不僅更加舒適,而且不太容易出現故障的不是與手動的低電平(內聯彙編)搞壞,也可能是最高效的方式成爲可能。