[英]What does the “denormal input” exactly mean in assembly when we consider using DAZ flag for SSE Floating Points
我已經閱讀了這篇文章和do-denormal-flags-like-denormals-are-zero-daz-affect-comparisons-for-equality ,我了解 FTZ 和 DAZ 標志之間的用法和區別。
DAZ 適用於輸入,FTZ 適用於來自 FP 操作的 output。
讓我感到困惑的是,如果設置了 FTZ ,那么匯編視圖中的非規范值來自哪里。 我認為它只能是作為直接操作數或來自.rodata
節(使用 RIP 相對尋址訪問)的常量值。
但是我在我的二進制文件中發現,這些地方沒有異常值,但它仍然存在 FP-ASSIST 問題,導致性能不佳。
如果我同時設置 DAZ 和 FTZ,問題就會消失並且性能會變得更好。 實際上,我什至在我的源代碼中都沒有找到任何非正規輸入。 我真的很困惑,異常值來自哪里?
另外一個問題,對於指令vmovsd 0x9498(%rip),%xmm0
,假設0x9498(%rip)
是一個非正規值,如果我們分別設置 FTZ 或 DAZ ,該指令執行后xmm0
會發生什么?
據我了解,DAZ 會將0x9498(%rip)
設為零並將 mov 0
移動到 xmm0; FTZ 會將0x9498(%rip)
移動到 xmm0 並發現它是異常的,因此將xmm0
刷新為零。 我不確定,是否正確?
非正規又名次正規是 IEEE 二進制格式中指數字段 = 0 的值。 https://en.wikipedia.org/wiki/Double-precision_floating-point_format
當 FP 數學指令(不是移動或純按位布爾值)讀取這樣的數字作為輸入操作數時,它必須在將尾數與另一個操作數對齊時處理這種特殊情況,以及應用尾數的隱式最高位時指數暗示為 0 或非零。
是的,大多數時候輸出上的 FTZ 就足夠了,因為大多數浮點值是其他 FP 計算的結果。 是的,FTZ 是必要的,因為正常數字上的 mul/div/add/sub 會產生不正常的結果。 (添加輸入需要相反的符號)。 另一個 IEEE “基本” 精確舍入運算 sqrt 不能創建次正規,因為它使數字更接近 1.0。
顯而易見的事情是使用perf record
來找出你在哪里獲得 FP 輔助,並在那里添加一些額外的檢查以打印或當你在那里發現異常時添加一些東西。 (然后在該分支中設置斷點,以便檢查情況。)
設置 FTZ 的非規范化可能來源(並非詳盡無遺),即除 FP 數學運算之外:
strtod
nextafter
這樣的 FP 位模式。 也可能作為exp
實現內部的一部分,將 integer 填充到double
的指數字段中。static double foo = DBL_MIN / 4.0;
將是編譯時異常。 但是您會在.rodata
或.data
中找到它們。 .data
中的非常量非零 static / 全局變量 go 。顯然,任何使用 integer 東西手動操作 FP 位模式也可以做到。 如何在沒有 AVX2 的情況下使用字節中的位在 ymm 寄存器中設置 dwords? (vmovmskps 的倒數)如果我沒有花費額外的指令來避免它,可能會產生比較的非正規輸入,但這是編譯器不會為你做的不尋常的手動向量化技巧。
立即數
x86 沒有 FP 立即數; 你必須mov rax, imm64
/ movq xmm0, rax
或類似的。 但是編譯器不會這樣做,因為從.rodata
加載通常更有效。
用於指令
vmovsd 0x9498(%rip),%xmm0
vmovsd
只是一個負載,並且總是精確地復制 64 位; 在架構上等效於vmovq
SIMD 整數負載。
它不會通過 ALU 運行該值,因此沒有 MXCSR 位對vmovsd
、FP shuffle 等有任何影響。只有執行實際 FP 數學並可能引發 FP 異常的指令才會受到影響。 您可以通過查看 asm 手冊條目的異常部分來判斷。 例如, roundsd
確實服從 DAZ 可能會在根據指定模式舍入之前將輸入舍入為零。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.