Нужно ли сохранять состояние FPU здесь?

Я написал простую совместную многопоточную библиотеку. В настоящее время я всегда сохраняю и восстанавливаю состояние fpu с помощью fxsave / fxrstor при переключении в новый контекст. Но необходимо ли это в соглашении о вызовах cdecl?

В качестве простого примера:

float thread_using_fpu(float x)
{
float y = x / 2; // do some fpu operation
yield();         // context switch, possibly altering fpu state.
y = y / 2;       // another fpu operation
return y;
}

Может ли компилятор сделать какие-либо предположения о состоянии FPU после вызова yield()?

2

Решение

Согласно БИНАРНЫЙ ИНТЕРФЕЙС ПРИЛОЖЕНИЯ SYSTEM V Приложение для архитектуры Intel386TM, стр. 3-12:

% st (0): если функция не возвращает значение с плавающей точкой, то это
регистр должен быть пустым. Этот регистр должен быть пустым до
вход в функцию.

% st (1) -% st (7):
Регистры с плавающей запятой не имеют определенной роли в
стандартная последовательность вызова. Эти регистры должны быть пустыми перед входом
и при выходе из функции.

Таким образом, вам не нужно переключать их контекст.

Другая, более новая версия говорит это:

Процессор должен находиться в режиме x87 при входе в функцию. Поэтому каждая функция, которая использует регистры MMX, должна выдавать
Инструкция emms или femms после использования регистров MMX, перед возвратом
или вызов другой функции. […] Управляющие биты регистра MXCSR сохраняются вызываемым абонентом (сохраняется при вызовах), а биты состояния сохраняются вызывающим абонентом (не сохраняются).
Регистр слова состояния x87 сохраняется вызывающим абонентом, тогда как элемент управления x87
слово сохранено.
[…] Все регистры x87 сохраняются вызывающими, поэтому вызывающие абоненты, использующие регистры MMX, могут использовать инструкцию более быстрого femms.

Таким образом, вам может понадобиться сохранить контрольное слово.

3

Другие решения

Нет. Вы не должны делать никаких сбережений государства. Если один поток находится в середине вычисления с плавающей запятой, где, например, установлен денормализованный флаг, и этот поток прерывается, то при возобновлении O / S или ядро ​​установит флаги, точно так же, как восстановит другие регистры. Точно так же вам не нужно беспокоиться об этом в yield ().

Изменить: Если вы делаете свое собственное переключение контекста, возможно, вам нужно будет сохранить контрольные флаги точности и округления, если вам нужно установить для них значения не по умолчанию. В противном случае снова ты в порядке.

2

По вопросам рекламы [email protected]