O Torvalds Linus

Сайт о *nix системах и всем что с ними связано

Содержимое регистров с плавающей точкой не восстанавливается сразу после того, как возобновляется выполнение процесса next. Однако флаг ts в

регистре его был установлен макросом uniazy_fpu (), поэтому, как только процесс next попытается выполнить инструкцию ESCAPE, MMX или SSE/SSE2, управляющий блок возбудит исключение “Устройство недоступно”, а ядро (точнее, обработчик этого исключения) вызовет функцию math state restore (). В этом обработчике процесс next идентифицируется как current.

void math_state_restore()

(

asm volatile (“cits”); / сбросить флаг TS в регистре crO / if (!(current ->flags & PF_USED_MATH)) init_fpu(current);

restore_fpu(current); current ->thread.status |= TS_USEDFPU;

)

Функция сбрасывает флаг ts в регистре его, чтобы последующие инструкции FPU, ММХ или SSE/SSE2, выполняемые процессом, не привели к возникновению исключения Устройство недоступно”. Если содержимое субполя thread.i387 смысла не имеет, т. е. флаг pf used math равен 0, вызывается функция init fpuo, которая сбрасывает субполе thread.i387 и устанавливает флаг pf used math процесса current. Затем вызывается функция restore fpu (), загружающая в регистры FPU соответствующие значения, хранящиеся в субполе thread.i387. Для этого применяется ассемблерная инструкция fxrstor или frstor, в зависимости от того, поддерживает ли процессор расширения SSE/SSE2. Наконец, функция math_state_restore() устанавливает флаг TS_USEDFPU.

Использование блоков FPU, ММХ и SSE/SSE2 в режиме ядра

Ядро само может использовать блоки FPU, ММХ и SSE/SSE2. Конечно, при этом оно не должно мешать вычислениям, которые выполняет текущий процесс в пользовательском режиме. Поэтому

? перед использованием сопроцессора ядро должно вызвать функцию kernel fpu begin (), КОТОрая вызывает функцию save init fpu (), Чтобы сохранить содержимое регистров, если процесс в пользовательском режиме выполнял инструкции FPU (флаг ts usedfpu), а затем сбрасывает флаг ts в регистре его;

? после использования сопроцессора ядро должно вызвать функцию kernei fpu end (), которая устанавливает флаг ts в регистре его.

Впоследствии, когда процесс пользовательского режима выполнит инструкцию сопроцессора, функция math state restore о восстановит содержимое регистров, аналогично тому, как это происходит при переключении процессов.

Следует отметить, ЧТО время работы функции kernel fpu begin () довольно велико, если текущий процесс пользовательского режима обращается к сопроцессору. Настолько велико, что этого достаточно для аннулирования выигрыша, полученного от применения блоков FPU, ММХ или SSE/SSE2. На практике ядро пользуется ими лишь в некоторых ситуациях, как правило, при переносе или очистке больших областей памяти или при вычислении контрольных сумм.

Add A Comment