簡體   English   中英

C ++中是否允許浮點表達式收縮?

[英]Is floating point expression contraction allowed in C++?

浮點表達式有時可以在處理硬件上收縮,例如使用融合乘法和加法作為單個硬件操作。

顯然,使用這些不僅僅是一個實現細節,而是由編程語言規范控制。 具體來說,C89標准不允許這樣的收縮,而在C99中,只要定義了某些宏,就允許它們。 請參閱此SO答案中的詳細信息。

但是C ++怎么樣? 浮點收縮是不允許的? 某些標准允許嗎? 普遍允許嗎?

摘要

允許收縮,但為用戶提供了禁用它們的工具。 標准中的語言不清楚是否禁用它們將提供所需結果的問題。

我在官方C ++ 2003標准和2017年n4659草案中對此進行了調查。 除非另有說明,否則C ++引用自2003年起。

超精密和范圍

文本“合同”沒有出現在任何一個文件中。 但是,第5條表達[expr]第10段(2017年8 [expr] 13中的同一文本)說:

浮動操作數的值和浮動表達式的結果可以以比該類型所需的精度和范圍更高的精度和范圍來表示; 因此不改變類型。

我希望這句話明確說明這個額外的精度和范圍是否可以自由使用(實現可以在某些表達式中使用它,包括子表達式,而不在其他表達式中使用它)或者必須統一使用(如果實現使用額外的精度) ,它必須在每個浮點表達式中使用它或根據一些其他規則(例如它可以使用一個精度用於float ,另一個用於double )。

如果我們巧妙地解釋它,則意味着,在a*b+ca*b可以用無限精度和范圍進行評估,然后可以用任何精度評估加法,並且范圍對於實現是正常的。 這在數學上等同於收縮,因為它與使用融合乘法 - 加法指令評估a*b+c具有相同的結果。

因此,通過這種解釋,實現可以合並表達式。

從C繼承的收縮

17.4.1.2 [lib.headers] 3(2017年的20.5.1.2 [標題] 3中的類似文字)說:

標准C庫的功能在18個附加標題中提供,如表12所示......

表12包括<cmath> ,第4段表示這對應於math.h 從技術上講,C ++ 2003標准是指C 1990標准,但我沒有它的電子形式,也不知道我的紙質副本在哪里,所以我將使用C 2011標准(但非官方草案N1570),其中C ++ 2017年草案指的是。

C標准在<math.h>定義了一個pragma FP_CONTRACT

#pragma STDC FP_CONTRACT on-off-switch

on-off-switch on以允許收縮表達式或off以禁止它們。 它還說pragma的默認狀態是實現定義的。

C ++標准沒有定義“設施”或“設施”。“設施”的字典定義是“為特定目的提供的地方,便利設施或設備”( New Oxford American Dictionary ,Apple Dictionary application version 2.2。 2(203))。 舒適性是“建築物或地方的理想或有用的特征或設施。”實用程序是為特定目的提供的有用特征,因此它似乎是一種設施,因此它包含在<cmath>

因此,使用此pragma應允許或禁止收縮。

結論

  • FP_CONTRACT打開時允許FP_CONTRACT ,默認情況下可能打開。

  • 8 [expr] 13的文本可以被解釋為有效地允許收縮,即使FP_CONTRACT關閉但是對於明確的解釋不夠清楚。

是的,這是允許的。

例如,在Visual Studio編譯器中,默認情況下, fp_contract打開狀態。 這告訴編譯器盡可能使用浮點收縮指令。 fp_contract設置為off以保留單個浮點指令。

// pragma_directive_fp_contract.cpp
// on x86 and x64 compile with: /O2 /fp:fast /arch:AVX2
// other platforms compile with: /O2

#include <stdio.h>

// remove the following line to enable FP contractions
#pragma fp_contract (off)

int main() {
   double z, b, t;

   for (int i = 0; i < 10; i++) {
      b = i * 5.5;
      t = i * 56.025;

      z = t * i + b;
      printf("out = %.15e\n", z);
   }
}

有關指定浮點行為的詳細信息。

使用GNU編譯器集合(GCC):

FP_CONTRACT pragma的默認狀態(C99和C11 7.12.2)。 該pragma未實現。 如果 - ffp-contract=fast-funsafe-math-optimizations-ffast-math被使用,表達式目前僅收縮。

暫無
暫無

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

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