Ленивые Потоки: Необязательный Параллелизм

Статья-гипотеза.

То, что описано, нигде не реализовано, хотя, в принципе, в Phantom ничего не мешает сделать это.

Эта идея пришла мне в голову уже давно и даже где-то мной была описана.

Поводом для описания сегодня является обсуждение сетевых драйверов Linux в комментариях к Анатомия водителя .

Сформулирую описанную там проблему так, как я ее понимаю: сетевой драйвер Linux работает в отдельном потоке, который читает полученные от устройства пакеты и обрабатывает их синхронно.

Он проходит через маршрутизацию, межсетевой экран и, если пакет не для нас, отправляет его на исходящий интерфейс.

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

В такой ситуации хотелось бы иметь механизм, который динамически порождает служебные потоки по мере необходимости, и достаточно дешевый механизм в ситуации, когда дополнительные потоки не нужны.

То есть хотелось бы вызов функции, который при необходимости можно преобразовать в запуск потока.

Но ценой вызова функции, если нить особо не нужна.

Эта идея пришла ко мне, когда я рассматривал совершенно фантастические модели для Phantom, включая модель актера с потоком, выполняющимся для любого вызова функции/метода.

Саму модель я отбросил, но идея ленивых потоков осталась и до сих пор кажется интересной.

Так.

Давайте предположим, что мы запускаем функцию void worker(packet), которая должна молча что-то выполнить.

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

Понятие «длинный» здесь открыто, но для него было бы разумно применить простую оценочную точку – если мы встретили свой собственный квант планирования – функция короткая.

Если бы при жизни функции произошло вытеснение и у нас отобрали процессор, это было бы долго.

Для этого запустим его через прокси lazy_thread(worker, package), который выполняет очень простую операцию — фиксирует ссылку на стек в момент перед вызовом рабочей функции в специальной lazy_threads_queue и заменяет стек на новый:

  
   

push( lazy_threads_queue, arch_get_stack_pointer() ); arch_set_stack_pointer(allocate_stack())

Если рабочий вернулся, то отмените эту операцию:

tmp = arch_get_stack_pointer() arch_set_stack_pointer( pop( lazy_threads_queue ) ); deallocate_stack(tmp)

И мы продолжим, как ни в чем не бывало.

Все обошлось нам в пару строк кода.

Если прошло значительное количество времени, а воркер все еще работает, мы проведем простую операцию — в момент изменения стека разделим потоки постфактум: сделаем вид, что внутри произошло полноценное создание потока.

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

Вы можете наложить дополнительные ограничения на точку принятия решения о запуске ленивого потока — например, средняя загрузка в течение 15 секунд будет меньше 1,5/процессор.

Если оно выше, распараллеливание вряд ли поможет; мы потратим больше ресурсов на создание бессмысленных тредов.

В современном мире, когда принято иметь 4 процессора в карманной машине и 16 в настольной машине, очевидна потребность в механизмах, которые помогают коду адаптироваться к нагрузочной способности оборудования.

Может быть и так? Теги: #threads #threads #parallelism #phantom #phantomos #phantom OS #программирование #Системное программирование

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.