是否有我可以讀取,修改或默認比較原子的類型? 或者我應該爲所有操作顯式使用所有類型的原子操作?原子指令和原子類型
回答
是的,你應該總是如果你需要原子性,使用原子類型或原子操作。沒有什麼不同。
形式上,沒有非原子類型默認提供任何類型的原子訪問。實際上,對於當前的CPU,任何內置類型都可以以原子方式讀取和寫入(但不能修改)。但是,這不是你有保證的東西,絕對不是你應該依賴的東西。這僅僅是一個實現細節。
當前CPU上的所有讀取和寫入均通過緩存。只有完整的緩存行(通常大約64-128字節)可以從主內存中讀取或寫回,並且緩存行是最大內置類型大小的倍數。這意味着如果一個類型正確對齊,它必然包含在單個緩存行中,這會自動使其讀寫成原子。但是,修改值是一個讀取 - 修改 - 寫入操作,這意味着即使每個步驟都是原子的,整個操作不是。
有不只是能夠讀取原子(或修改)的值更原子性,例如有您可能需要正確排序保證。即使讀取和寫入是原子性的,如果不按照預期的順序通過不同的處理器看到修改,代碼將無法正常工作。編譯器和CPU(在一些合理的限制內)允許重新排序指令,包括加載和存儲。但是,這可能意味着您的代碼無法正確執行。因此
原子操作有一個「內存模型」與他們有聯繫,它允許你提供什麼的之前發生,保證你的線程之間和相關或不相關的數據之間需要更多的信息。請參閱GCC Wiki以瞭解每種模式的詳細說明。
默認情況下,原子操作選擇順序一致模式,這是最嚴格的限制是最安全的模式。如果你知道你不需要某些保證,你可以選擇一個不同的模型,這可能(或者可能不會),這取決於體系結構)會導致生成更高性能的代碼。
與內存模式的好處是,他們抽象的實現細節,建築pecularities和成decribes你的算法要求,並保證這些要求得到滿足形式編譯巫術。
通常情況下,編譯器就可以正常使用非原子機器指令,仍然保證您的要求得到滿足(這可能會失去一個或另一個重新排序)。這取決於目標硬件如何工作的實際細節以及您需要什麼保證。
總而言之,利用原子能和內存模型不僅更加舒適,而且不太容易出現故障的不是與手動的低電平(內聯彙編)搞壞,也可能是最高效的方式成爲可能。
結賬http://en.cppreference.com/w/cpp/atomic/atomic。
它提到了std::atomic<T>
,就像@IgorTandetnik在其中一條評論中提到的一樣。
- 1. Boost原子128位原子類型x86_64
- 2. 原子類型和線程
- 3. 原子指令:IF和循環
- 4. Elisp原子類型分類
- 5. OBJC_ASSOCIATION_ASSIGN是指原子還是非原子?
- 6. 原子類型的numeric_limits
- 7. 原子類型的大小
- 8. JavaScript中的原型/子類
- 9. python原子數據類型
- 10. 原子數據類型在C#原子(線程安全)?
- 11. 原子操作和原子交易
- 12. 原子或巨型
- 13. 組裝原型指令
- 14. C函數原型和.set指令
- 15. 我聽說INC指令不是原子的。那麼,CAS指令如何可以是原子的?
- 16. MinGW 4.6.2 std ::原子指針
- 17. 比較語義與std ::原子類型
- 18. 原型Class.create沒有正確的子類
- 19. C++原子與非平凡類型?
- 20. Visual C++ 2010原子類型支持?
- 21. 什麼是原子商店類型?
- 22. 原子和參考
- 23. 原始數據類型在java中是原子的
- 24. C++ 11:原子:: compare_exchange_weak支持非原始類型嗎?
- 25. 指定原型的原型:在命令行上生成
- 26. Maven原型:子包名
- 27. 組合原子和非原子變量和緩存
- 28. angularjs使用ng-repeat和原始數據類型嵌套指令
- 29. js原型class.create子類和超類變量之間的共存
- 30. 配置原子IDE與原子轉輪
@Damon我認爲你應該把它作爲答案 – Slava
'std :: atomic'是一種你總是自動讀取和修改的類型(準確地說,轉換爲'T'自動執行原子加載,並從'T'執行一個原子存儲)。我不確定你的意思是「比較原子」。 –