Ответ 1
Ничего себе, это было задано в декабре, и никто не ответил на это? Некоторые из этого вы, возможно, уже знаете, и я приношу свои извинения, если так.
Это просто потому, что шаги для выполнения wrmsr медленны. Легче и быстрее просто загружать регистры сегментов при переключении задач.
На очень современных процессорах Intel добавление команд "rdfsbase", "wrfsbase", "rdgsbase" и "wrgsbase" обеспечивает прямой доступ к базовым регистрам FS и GS с гораздо меньшими трудностями, чем раньше. Фактически, ядро может разрешить их использование из пользовательского режима, если ему это нравится. Возможно, вы захотите проверить, используют ли современные ядра Linux преимущество wrfsbase, чтобы сделать ненужным выделение области TLS ниже 4 ГБ.
Я не знаю, как это работает в Linux, но Windows NT, начиная с Windows 7, имеет диспетчеризацию потоков пользовательского режима в качестве дополнительной функции для разработчиков приложений. Как и в Linux и Mac OS X, Windows реализует поточно-локальное хранилище на x86, используя базовый адрес сегментных регистров (GS в x86-64 Windows). Эта функция похожа на волокна, за исключением того, что программа может переключать свой собственный контекст потока с другим способом, который также распознается ядром.
Планирование пользовательского режима в Windows реализовано путем создания LDT с сегментами, указывающими на блоки TLS (называемые "Блоки среды нитей" или TEB, в Windows) для каждого потока планирования. Пользовательский режим может затем переключать потоки, перезагружая базу GS в дополнение к контекстному коммутатору. Для этого требуется, чтобы TEB были ниже 2 ^ 32, как в примечании к производительности Linux arch_prctl - в противном случае для пользовательского режима планирования требовался бы вызов ядра NT каждый раз, когда он переключился на другой поток, чтобы сделать wrmsr, победив всю точку планирования пользовательского режима.
В Windows 8.1 была добавлена поддержка wrgsbase, и она также включена для пользовательского режима. Планирование пользовательского режима в 8.1 использует wrgsbase вместо перезагрузки сегмента GS и LDT, если у него есть процессор.