4

У меня есть небольшой пример проблемы, возникшей при переходе от VS2013 к VS2015. В VS2015 далее упомянутый пример кода вызывает недействительную операцию с плавающей запятой.Другая оптимизация в VS2015 vs VS2013 вызывает исключение с плавающей запятой

enter image description here

int main() 
{ 
    unsigned int enableBits = _EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID; 

    _clearfp(); 
    _controlfp_s(0, ~enableBits, enableBits); 

    int count = 100; 
    float array[100]; 

    for (int i = 0; i < count; ++i) 
    { 
     array[i] = (float)pow((float)(count - 1 - i)/count, 4); //this causes exception in VS2015 
    } 

    return 0; 
} 

Это происходит только в режиме выпуска так что его, вероятно, вызвано различной оптимизации. Что-то не так с этим кодом или это ошибка в VS 2015?

Его трудно найти такие вопросы, как они по всей базе кода, так что я ищу какое-то систематическое исправление не обходной путь (например, использовать другую переменную вместо я, который работает)

Я также проверил генерироваться а в VS2013 он использует целый 128-битный реестр для выполнения 4 операций с плавающей запятой в одном разделе. В VS2015, похоже, всего 2 операции с плавающей точкой, а остальная часть реестра равна нулю (или некоторому мусору), что, вероятно, вводит это исключение.

Инструкция, которая вызывает исключение, помечена на картинке.

VS2013 VS2013

и VS2015 enter image description here

Любая помощь будет оценена. Спасибо.

+0

Хм. Ваш код работает для меня (Release/x64) с включенной полной оптимизацией. Является ли ваш ВС актуальным? У вас есть «специальные» настройки компилятора? –

+0

Я использовал обновление VS2015 3. Я использовал стандартные настройки для выпуска + Оптимизация (Максимизировать скорость/O2) и включить встроенные функции (Да/Oi) – Bezousek

ответ

1

Это выглядит как взаимодействие с вами с использованием исключений с плавающей запятой, но также позволяет оптимизировать с плавающей запятой.

Что делает код, так это 2 итерации сразу (разворачивание цикла), но использует divps, который делает 4 деления сразу (из 4 поплавков в регистре XMM). Верхние 2 поплавки в регистре XMM не используются и равны нулю. Поскольку результат деления значений в этих слотах не используется, это обычно не имеет значения. Однако, поскольку вы устанавливаете настраиваемую обработку исключений, возникает недопустимое исключение op, которое вы видите, даже несмотря на то, что его генерирующие значения не используются.

Ваш выбор - как я вижу, - установить/fp: strict, который отключит оптимизацию, поэтому сделайте эту работу (но это, очевидно, сделает код медленнее) или удалит вызов controlfp.

+0

Спасибо за комментарий. Эти настройки строго строятся, но проблема в том, что я не знаю, где я должен ее установить. У меня, как правило, сотни файлов с вычислениями, и я не хочу его уменьшать везде. Знаете ли вы, что происходит в VS2015 и VS2013, где он отлично работает даже в/fp: точным? – Bezousek

 Смежные вопросы

  • Нет связанных вопросов^_^