2016-03-12 3 views
2

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

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

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()?

+3

Нет, обычное соглашение обязывает государство FPU быть пустым после входа и выхода (если явно не используется для возвращаемого значения). – Jester

+0

Спасибо, у вас есть источник для этого? Я сам не мог найти об этом. Не нужно сохранять и восстанавливать 512-байтовый буфер каждый раз, чтобы действительно повысить производительность, и я хочу быть на 100% уверенным, что это не вызовет никаких проблем. – user5434231

ответ

3

В соответствии с SYSTEM V APPLICATION BINARY INTERFACE Intel386TM Architecture Processor Supplement, стр 3-12:

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

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

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

Другой, newer version говорит, что это:

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

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

2

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

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

+0

Просто, чтобы уточнить, я выполняю свое собственное переключение контекста, не используя потоки, управляемые OS. – user5434231