Как использовать gnu g cc flag -mpc32, -mpc64 и -mpc80? - PullRequest
0 голосов
/ 24 января 2020

Я получил эти флаги G CC из руководства по компилятору GNU G CC . Но когда я попытался использовать эти флаги (-mpc32, -mpc64 и -mpc80), я не смог наблюдать за поведением. Поэтому мне нужна помощь по использованию этих флагов с примером кода.

пример кода, который я пробовал: test. cpp

#include<stdio.h>
#include<iomanip>
#include<math.h>

int main()
{
    double weight = 1.0f;
    double roiSize = 137.142364501953125f;
    double thresholdValue = 5400.0f;
    double alpha = weight / (roiSize * thresholdValue * thresholdValue);
    std::cout<<std::setprecision(100)<<"alpha = "<<f<<std::endl;
    double test = pow(roiSize, 10);
    std::cout<<std::setprecision(100)<<"alpha = "<<f<<std::endl;
}

Параметры компиляции:

g++ -mpc32 test.cpp
g++ -mpc64 test.cpp
g++ -mpc80 test.cpp

1 Ответ

2 голосов
/ 26 января 2020

Самым простым способом проверки различной точности x87 может быть использование long double, что для целей x86 является 80-битным типом x87. (За исключением Windows, где long double = double).

Другое преимущество long double состоит в том, что вам не нужно компилировать с -m32, чтобы вообще использовать x87. (По умолчанию для -m64 установлено значение -mfpmath=sse; двойная математика и вычисление с плавающей запятой будут выполняться в регистрах XMM с шириной шрифта, не расширенной до внутренней точности x87. Но long double всегда будет использовать x87, поскольку SSE / SSE2 не может сделать 80 бит). TL: DR: в обычном 64-битном системном сборке с gcc -mpc32 foo.c, -mpc32 не будет иметь никакого значения для математики по double переменным, потому что он даже не использует устаревший x87 FPU.

Кстати, этот тестовый пример также зависит от компиляции со значением по умолчанию -O0, иначе произойдет постоянное распространение во время компиляции. (И это вряд ли будет уважать -mpc32.)


137.142364501953125f - это константа float, округленная до значения с плавающей точкой, перед использованием в качестве инициализатора для double. Таким образом, все ваши начальные значения округлены до ближайшего float, несмотря на то, что хранятся как double. Я предполагаю, что деление не точное, поэтому вы все равно получите округление.


Я предполагаю, что эти параметры просто устанавливают точность x87 при запуске. Код запуска MST C CRT, очевидно, делает то же самое, по умолчанию устанавливая 64-битную точность (53-битная мантисса, как double, не полная точность). См. Статью Брюса Доусона Intermediate Float-Precision ; одна из серии статей о ФП. Индекс в этом .

Вы можете посмотреть на asm, генерируемый компилятором, чтобы увидеть, как он выполняет FP математику: использование fld / fmul / fstp равно x87 и будет зависит от точности x87, установленной в регистре управляющих слов x87.

movsd / mulsd - это SSE2, а точность задается инструкцией; никакие биты состояния / управления не могут переопределить его. (В MXCSR можно изменить только режим округления и обработку субнормалей.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...