fp_contract
pragma
Bestimmt, ob Gleitkommakontraktion stattfindet. Eine Gleitkommakontraktion ist eine Anweisung wie Fused-Multiplikations-Add (FMA), die zwei separate Gleitkommavorgänge in einer einzigen Anweisung kombiniert. Die Verwendung dieser Anweisungen kann sich auf die Gleitkommagenauigkeit auswirken, da der Prozessor nicht nach jedem Vorgang rundet, sondern nur einmal nach beiden Vorgängen rundet.
Syntax
#pragma fp_contract (
{ }on
|off
)
Hinweise
Wenn Sie die Standardcompileroptionen verwenden, wird off
der Compiler aufgefordert, fp_contract
einzelne Gleitkommaanweisungen beizubehalten. Legen Sie fp_contract
fest, dass on
Gleitkommakontraktionsanweisungen verwendet werden sollen, sofern möglich. Dieses Verhalten ist neu in Visual Studio 2022, Version 17.0. In früheren Compilerversionen ist fp_contract
standardmäßig auf on
.
Wenn Sie die Standardcompileroptionen verwenden, lautet dies fp_contract
on
. Diese Einstellung weist den Compiler an, soweit möglich Gleitkommakontraktionsanweisungen zu verwenden. Legen Sie diese Einstellung fp_contract
fest, off
um einzelne Gleitkommaanweisungen beizubehalten. In Visual Studio 2022, Version 17.0 und höher, fp_contract
wird standardmäßig auf off
.
Weitere Informationen zum Gleitkommaverhalten finden Sie unter /fp
(Angeben des Gleitkommaverhaltens)
Weitere Gleitkommadirektiven pragma sind:
Beispiel
Die /fp:fast
Compileroption aktiviert standardmäßig Kontraktionen, aber die #pragma fp_contract (off)
Direktive in diesem Beispiel deaktiviert. Der aus diesem Beispiel generierte Code verwendet keine Fused-Multiplikationsanweisung, auch wenn er auf dem Zielprozessor verfügbar ist. Wenn Sie auskommentieren #pragma fp_contract (off)
, kann der generierte Code eine Fused-Multiplikations-Add-Anweisung verwenden, wenn er verfügbar ist.
// pragma_directive_fp_contract.cpp
// On x86 and x64 compile with: /O2 /fp:fast /arch:AVX2
#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);
}
}
out = 0.000000000000000e+00
out = 6.152500000000000e+01
out = 2.351000000000000e+02
out = 5.207249999999999e+02
out = 9.184000000000000e+02
out = 1.428125000000000e+03
out = 2.049900000000000e+03
out = 2.783725000000000e+03
out = 3.629600000000000e+03
out = 4.587525000000000e+03