Какие накладные расходы задействованы при переключении режима - PullRequest
14 голосов
/ 07 декабря 2009

Много раз я читал / слышал аргумент, что много системных вызовов и т. Д. Были бы неэффективными, так как приложение переключает режим, то есть переходит из пользовательского режима в режим ядра, а после выполнения системного вызова начинает выполняться в пользовательском режиме. снова переключив режим.

У меня вопрос, что такое издержки переключения режима? Кэш процессора становится недействительным, или записи tlb сбрасываются, или что происходит, что приводит к накладным расходам?

Обратите внимание, что я спрашиваю о накладных расходах, связанных с переключением режима, а не переключением контекста. Я знаю, что переключение режимов и переключение контекста - это две разные вещи, и я полностью осведомлен о накладных расходах, связанных с переключением контекста, но чего я не понимаю, так это то, какие накладные расходы вызваны переключением режимов?

Если возможно, предоставьте некоторую информацию о конкретной * nix-платформе, такой как Linux, FreeBSD, Solaris и т. Д.

Привет

Лали

Ответы [ 2 ]

12 голосов
/ 07 декабря 2009

На простом переключателе режима не должно быть кэша ЦП или сброса TLB.

Быстрый тест говорит мне, что на моем ноутбуке с Linux процесс пользовательского пространства занимает около 0,11 микросекунды, чтобы выполнить простой системный вызов, который выполняет незначительный объем работы, кроме перехода в режим ядра и обратно. Я использую getuid (), который копирует только одно целое число из структуры в памяти. strace подтверждает, что системный вызов повторяется МАКС. Раз.

#include <unistd.h>
#define MAX 100000000
int main() {
  int ii;
  for (ii=0; ii<MAX; ii++) getuid();
  return 0;
}

На моем ноутбуке это занимает около 11 секунд, измеряется с помощью time ./testover, а 11 секунд, разделенные на 100 миллионов, дают 0,11 микросекунды.

Технически, это два переключателя режима, поэтому я полагаю, что вы могли бы утверждать, что переключение одного режима занимает 0,055 микросекунд, но односторонний переключатель не очень полезен, поэтому я рассмотрю число туда и обратно будь более уместным.

2 голосов
/ 07 декабря 2009

Существует много способов переключения режимов на процессорах x86 (которые я предполагаю здесь). Для пользователя, вызываемого функцией, нормальный способ - выполнить переход задачи или вызов (называемый «Ворота задачи» и «Ворота вызова»). Оба из них включают переключение задач (эквивалентно переключению контекста). Добавьте к этому немного обработки перед вызовом, стандартную проверку после вызова и возврат. Это округляет минимум до безопасного режима.

Что касается времени Эрика, я не эксперт по Linux, но в большинстве операционных систем, с которыми я имел дело, простые системные вызовы кэшируют данные (если это можно сделать безопасно) в пространстве пользователя, чтобы избежать этих издержек. И мне кажется, что getuid () будет основным кандидатом для такого кэширования данных. Таким образом, синхронизация Эрика может быть скорее отражением издержек обработки предварительного переключения в пользовательском пространстве, чем что-либо еще.

...