簡體   English   中英

為什么邏輯 AND/OR 的左操作數不依賴於父評估?

[英]Why do left operands of logical AND/OR not carry dependency to the parent evaluation?

根據C++標准:

如果 - 將 A 的值用作 B 的操作數,則評估 A 對評估 B 具有依賴性,除非:

— B 是對 std::kill_dependency (29.3) 的任何特化的調用,或

— A 是內置邏輯 AND(&&,參見 5.14)或邏輯 OR(||,參見 5.15)運算符的左操作數,或

— A 是條件 (?:, 見 5.16) 運算符的左操作數,或

— A 是內置逗號 (,) 運算符 (5.18) 的左操作數; (...)

我可以理解為什么在關系之前排序的依賴會在 kill_dependency 調用時停止,但是為什么邏輯 AND、OR、逗號等運算符也會破壞依賴鏈?

這是否意味着下面的代碼具有未定義的行為?

//thread1
int y = 2
atomicVal.store(true);

//thread2 
auto x = atomicVal.load(std::memory_order_consume);
cout << x && y;

memory_order_consume試圖公開用於 C++ 的 asm 級 CPU 功能。 (它暫時被棄用,直到它可以被重新設計為編譯器可以在實踐中實現的東西,並且在源代碼中不需要太多的kill_dependency噪音)。 了解 CPU 行為是了解 C++ 的設計的關鍵,旨在公開它。

這都是關於數據依賴關系,而不是像條件分支這樣的控制依賴關系。 C++11:memory_order_relaxed和memory_order_consume之間的區別[[carries_dependency]]是什么意思以及如何實現有更多細節。

例如add x2, x2, x3指令在其兩個輸入寄存器都准備好之前不能執行,並且ldr w1, [x2]也不能在地址准備好之前執行加載,所以如果x2來自另一個加載,它會自動排序在這個之前。 (假設 CPU 硬件設計為不違反因果關系,例如通過進行價值預測或 DEC Alpha 在極少數情況下違反因果關系的任何事情)。 但是cbz w1, reg_was_zero是可以預測的,所以讓reg_was_zero: ldr w3, [x4]等待產生 w1 的負載是不夠的。 (這是 AArch64 asm,順便說一句,一種保證依賴排序的弱排序 ISA。)

||的短路評估 or left && right在邏輯上與if(left) right相同,因此即使左側尚未執行,也可以預期分支預測 + 推測執行會在右側運行。 沒有數據依賴,只有控制依賴。

很明顯,逗號left, right並沒有在兩邊之間建立任何聯系,它基本上是一種填塞left; right; left; right; 成一個表達式。

當然,如果你在左右兩邊都使用相同的變量,數據依賴可以這樣存在,但它不是由操作員創建的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM