OSDev

для всех
Текущее время: 21 май 2024, 13:34

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 102 ]  На страницу Пред.  1, 2, 3, 4, 5, 6 ... 11  След.
Автор Сообщение
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 10 июл 2011, 15:38 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
SII писал(а):
Ну, если используется аппаратная многозадачность и защита портов от Интел, то такое решение становится понятным. Другое дело, что целесообразность применения этих особенностей архитектуры ИА-32 представляется сомнительным, но если уж они используются, то действовать приходится в диктуемых ими рамках...

Аппаратная многозадачность у меня почти не используется, т.к. классических прыжков между TSS нет, а регистры сохраняются только в стеке. Просто у каждого потока индивидуальный TSS.ESP0, указывающий на структуру регистров этого потока.

IO_Map у меня и правда практически не используется. При создании я рассчитывал, что пригодится в будущем.

phantom-84, для стека ядра используется глобальная память, и при переключении потоков стек ядра переотображается автоматически.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 10 июл 2011, 16:50 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
SII писал(а):
А зачем передавать управление другому потоку пользователя, если для первого в данный момент выполняется код ядра? Такое переключение просто должно быть отложено, и всё.
При таком подходе слишком неравномерно будет распределяться время между потоками, даже если штрафовать потоки, работающие дольше других в режиме ядра. К тому же сам поток может уйти на ожидание или даже добровольно отдать управление в режиме ядра.

Цитата:
А зачем нужна эта "многоуровневая обработка прикладных запросов"?
Я имел в виду сложную обработку запросов, последовательно выполняемую разными компонентами ядра и требующую достаточной глубины стека.

Цитата:
Кстати говоря, а зачем такая большая ("порядка 1 кб") структура потока?..
Я сейчас статически выделяю буфер для сохранения контекста FPU/SSE - это 0,5 кб, плюс "основные поля", плюс управление рабочим набором, плюс управление обработкой исключений в потоке. Про структуру процесса я вообще не говорю, хотя она и разделена на несколько частей, большинство из которых находится в области локальных данных ядра.

Himik писал(а):
для стека ядра используется глобальная память, и при переключении потоков стек ядра переотображается автоматически.
Физически это один и тот же стек? Если нет, то я это называю локальной памятью.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 10 июл 2011, 17:42 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1418
phantom-84 писал(а):
SII писал(а):
А зачем передавать управление другому потоку пользователя, если для первого в данный момент выполняется код ядра? Такое переключение просто должно быть отложено, и всё.
При таком подходе слишком неравномерно будет распределяться время между потоками, даже если штрафовать потоки, работающие дольше других в режиме ядра.


Если ядро сделано настолько плохо, что по полчаса обрабатывает существенную часть запросов, то этому случаю уже ничего не поможет. Обсуждать такое положение вещей смысла нет, потому будем считать, что ядро достаточно вменяемо спроектировано и реализовано, а посему не тратит на обработку запроса потока очень много времени, а впустую его вообще не расходует. Замечу, что абсолютное время обработки конкретного запроса, выраженное, например, в миллисекундах, может быть довольно большим (предположим, что обработку пришлось приостановить, поскольку потребовалось загрузить страницу памяти с диска), однако время, затраченное процессором на обработку запроса, в любом случае невелико, ну а пока обработка запроса приостановлена, процессор предоставлен другому потоку, а не работает вхолостую.

Поскольку мы предположили, что само по себе ядро достаточно быстрое, можно считать, что типичный квант времени, выделяемый потоку, будет существенно больше типичного времени, необходимого ядру на обработку запроса. В такой ситуации "отъеданием" времени чужого потока можно попросту пренебречь, поскольку: а) потери будут невелики (обработка занимает лишь малую часть времени, выделенного потоку); б) случаться такая ситуация будет довольно редко (ведь для этого нужно, чтобы запрос от потока поступил "под занавес" его кванта, а не в начале или середине).

Не соблюдаться предположение о соотношении величины кванта и времени обработки может лишь в двух случаях: либо система дубовая (что мы отвергаем), либо квант слишком мал. Однако сильное его уменьшение нецелесообразно, поскольку резко увеличивает накладные расходы на постоянное переключение потоков, ну а попытки справедливо делить оставшееся от переключений время лишь ещё больше его уменьшат, и в итоге производительность системы сильно снизится.

Наконец, ничто не мешает легко и непринуждённо штрафовать "провинившийся" поток. Для этого достаточно хранить для него две величины кванта времени: расчётную ("по умолчанию") и ту, которая будет ему выделена при следующей постановке на процессор. Последняя устанавливается равной расчётной, если поток снят с процессора в результате истечения его кванта, и уменьшается, если истечение кванта наступило в момент, когда ядро обрабатывало запрос этого потока, причём величина уменьшения зависит от того, сколько лишних тиков израсходовало ядро. Таким образом, следующий поток не потеряет своего законного времени, он лишь будет поставлен на процессор чуть позже, чем при простом переключении по таймеру, однако эта задержка с лихвой компенсируется исключением времени, необходимого на лишние "телодвижения" системы для сохранения состояния обработки запроса от одного потока, потом для возобновления этой обработки и т.д. и т.п. Попросту говоря, упрощение логики обработки, в том числе и учёта времени, позволит уменьшить расход времени на работу самой системы, а значит, больше времени останется на работу самих потоков, что, вообще говоря, и является самым важным.

В общем, проблема представляется мне надуманной.

Цитата:
К тому же сам поток может уйти на ожидание или даже добровольно отдать управление в режиме ядра.


"Сам поток" не может "уйти на ожидание" в ядре, поскольку в этот момент выполняется не код потока, а код ядра. Как ядро делит своё время -- это его дело, но поток на это никак повлиять не может. Если же "уходит" ядро, обрабатывающее запрос потока, и управление получает другой поток, то перезагружаются и счётчики времени, поэтому один поток не будет в сколько-нибудь заметных дозах пожирать чужое время.

Цитата:
Я имел в виду сложную обработку запросов, последовательно выполняемую разными компонентами ядра и требующую достаточной глубины стека.


Честное слово, я не вижу ни одного случая, где реально может потребоваться такая сложная глубоко вложенная обработка.

Цитата:
Я сейчас статически выделяю буфер для сохранения контекста FPU/SSE - это 0,5 кб, плюс "основные поля", плюс управление рабочим набором, плюс управление обработкой исключений в потоке.


Что такое рабочий набор, мне не очень понятно; управление обработкой исключений в потоке требует, ИМХО, мизерного объёма (правда, это сильно зависит от того, как именно она организована). Но в пределах полукилобайта расход действительно оправдан, раз уже сохраняется контекст FPU/SSE: понятно, что его не соптимизируешь.

Цитата:
Про структуру процесса я вообще не говорю, хотя она и разделена на несколько частей, большинство из которых находится в области локальных данных ядра.


Где находятся, в данном случае не шибко важно, роль играет именно общий расход памяти. И дело не в том, что её мало (на ПК её хоть залейся, это вот попробуй на АРМе обойтись лишь встроенной памятью -- от 16 до пары сотен килобайт ОЗУ и от нескольких десятков до нескольких сотен килобайт флэш-памяти). Нужно помнить, что "раздувание" структур данных ведёт не только к расходу ОЗУ, но и к постоянной пересылке данных между ОЗУ и кэшем, что пагубно влияет на производительность. Собственно, грамотная структура данных в любой задаче -- непременное условие получения хорошего результата...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 10 июл 2011, 18:17 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
SII писал(а):
Если ядро сделано настолько плохо, что по полчаса обрабатывает существенную часть запросов, то этому случаю уже ничего не поможет.

Кажется я понял о чём речь. Просто в ядре находятся сложные модули и подсистемы, как в монолитах. Они могут работать долго, так как это не элементранные операции дать/взять.
phantom-84 писал(а):
Физически это один и тот же стек? Если нет, то я это называю локальной памятью.

Один и тот же. Всего один стек на каждый процессор.
В момент переключения из пользовательского уровня в ядро, стек указывает на текущий поток (куда "оседают" регистры), а затем указатель переключается на стек текущего процессора. Коллизий в ядре не возникает, потому что ядерная обработка не вытесняемая, флаг прерываний просто сброшен.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 10 июл 2011, 18:45 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1418
Himik писал(а):
SII писал(а):
Если ядро сделано настолько плохо, что по полчаса обрабатывает существенную часть запросов, то этому случаю уже ничего не поможет.

Кажется я понял о чём речь. Просто в ядре находятся сложные модули и подсистемы, как в монолитах. Они могут работать долго, так как это не элементранные операции дать/взять.


Поправка: как в плохих монолитах. В хороших монолитах такие вещи реализовались задачами режима пользователя. Правда, сейчас такие монолиты нередко объявляют микроядрами, но это не соответствует действительности: все ключевые компоненты системы находятся в ядре, используют общее адресное пространство и т.д., так какое же это микроядро?

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 10 июл 2011, 19:41 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
SII писал(а):
Замечу, что абсолютное время обработки конкретного запроса, выраженное, например, в миллисекундах, может быть довольно большим (предположим, что обработку пришлось приостановить, поскольку потребовалось загрузить страницу памяти с диска), однако время, затраченное процессором на обработку запроса, в любом случае невелико, ну а пока обработка запроса приостановлена, процессор предоставлен другому потоку, а не работает вхолостую.
У меня обработка запроса может быть приостановлена не только в момент выполнения запроса, но и в процессе его обработки. Кроме того, на время обработки запроса не накладывается никаких ограничений. Только драйверы должны устанавливать таймаут на отклик от устройств.

Цитата:
"Сам поток" не может "уйти на ожидание" в ядре, поскольку в этот момент выполняется не код потока, а код ядра.
Опять расхождения в терминологии (и еще видимо в архитектуре). У меня исполняемой сущностью являются только потоки. Когда выполняется код ядра, то фактически выполняется либо поток ядра, либо прикладной поток, работающий в режиме ядра. У меня монолитно-модульная архитектура.

Цитата:
Честное слово, я не вижу ни одного случая, где реально может потребоваться такая сложная глубоко вложенная обработка.
Когда идет вложенное обращение к различным компонентам ядра, часто являющимся абсолютно независимыми модулями, то и глубина в 8-10 кб часто может быть недостаточной - приходится использовать специальные средства проверки текущей глубины стека (включая специальные системные вызовы), а также давать специальные рекомендации по разработке модулей ядра, направленные прежде всего на минимизацию размера стековых кадров используемых в них подпрограмм.

Цитата:
Но в пределах полукилобайта расход действительно оправдан, раз уже сохраняется контекст FPU/SSE: понятно, что его не соптимизируешь.
На самом деле даже здесь есть варианты. К примеру можно отделить этот буфер от структуры потока и выделять его только при первом появлении соответствующих инструкций в данном потоке.

Цитата:
Где находятся, в данном случае не шибко важно, роль играет именно общий расход памяти. И дело не в том, что её мало (на ПК её хоть залейся, это вот попробуй на АРМе обойтись лишь встроенной памятью -- от 16 до пары сотен килобайт ОЗУ и от нескольких десятков до нескольких сотен килобайт флэш-памяти). Нужно помнить, что "раздувание" структур данных ведёт не только к расходу ОЗУ, но и к постоянной пересылке данных между ОЗУ и кэшем, что пагубно влияет на производительность. Собственно, грамотная структура данных в любой задаче -- непременное условие получения хорошего результата...
Я считаю, что расходую память для структур процессов достаточно эффективно. Да, всегда есть небольшие противоречия между расходуемым объемом памяти и скоростью (например, массив счетчиков заполненности таблиц страниц для высвобождения неиспользуемых таблиц страниц, как альтернатива обычному поиску таких страниц или вообще их подвисанию в таком состоянии). Я считаю, что нашел вполне разумный компромисс.

Цитата:
Так что, думаю, лучше было бы пересмотреть концепцию и вынести такие вещи наружу. Ядро резко упростится, ну а потери времени на переключение контекста для вызова таких внешних модулей полностью компенсируются уменьшением накладных расходов на собственно ядро (в частности, на учёт времени). Этим, кстати, хороший монолит отличается от настоящего микроядра, как оно понималось изначально и в котором всё подряд разнесено по разным адресным пространствам, из-за чего на обработку даже простого запроса требуется гора переключений контекста.
Я вполне допускаю возможность выноса некоторых служб в отдельные процессы. Но я не могу и не хочу выносить из ядра такие его подсистемы, как файловая, хотя уже сейчас почти все системные вызовы могут обрабатываться независимыми модулями, однако они должны работать в режиме ядра (по крайней мере их первичные обработчики).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 10 июл 2011, 23:41 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
phantom-84, я так понял, у тебя есть как пользовательские, так и ядерные потоки. Плохо только, что стеки для ядерных потоков сильно ограничены в размере. Получается как бы сапожник без сапог, ядро не может обеспечить комфортной работы для самого себя. Надо над этим делом подумать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 11 июл 2011, 10:58 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Существенной разницы между ними нет, просто одни предназначены для работы исключительно в режиме ядра, а другие в обоих режимах (имеют не только стек ядра, но и прикладной стек). Потоки ядра не являются независимыми от вирт. адр. пространства, они привязаны к пространству первичной задачи. Размер стека выбран таким, чтобы обеспечить комфортную работу ядра и его компонентов (я проверяю ядро на максимальную глубину стека при вложенных вызовах), хотя "неправильно" написанные сторонние модули конечно могут привести к переполнению стека, а дополнительные компоненты, встраиваемые в цепочку вложенных вызовов, могут привести к недоступности компонентов, находящихся в конце этой цепочки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 11 июл 2011, 12:10 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1418
Если не секрет, откуда вы позаимствовали столь страшные навороты (саму идею)? Или самостоятельная придумка?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Планировщик
СообщениеДобавлено: 11 июл 2011, 13:20 
Аватара пользователя

Зарегистрирован: 20 апр 2011, 10:54
Сообщения: 145
Кстати, рас уж такая тусовка...
Хранить регистры (т. е. Task state) в стеке юзерского потока = BAD IDEA?!!

_________________
Found a CPU. LAPIC ID: 00


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 102 ]  На страницу Пред.  1, 2, 3, 4, 5, 6 ... 11  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 77


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB