реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Стек для прерываний, и недостаток таймеров
defunct
сообщение Jul 28 2009, 01:33
Сообщение #16


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Zlumd @ Jul 28 2009, 04:05) *
Так это не несколько паралельно выполняющихся задач. Это одна задача.

Как не крути а процессор один, и для него любая программа будет одной задачей.
Вопрос в абстрагировании. Ниже приведено две реализации одного и того же:

1)
Код
task()
{
   while( true)
   {
       wait_sema( sema_x);
       do_stuff();
   }
}


2)
Код
task()
{
   if ( sema_x)
      do_stuff();
}


Пусть памяти всего 1KB, и есть 3 таска. Во втором варианте каждый таск может запросто взять и пользовать например 512 байт под временный буфер, в первом же 3x512B > 1KB и приехали.

Цитата
Каждая задача подразумевает сохранение всех локальных переменных, которые лежат в стеке, при переключении с задачи на задачу

Дайте каждой задаче static контекст с которым она работает, оформите как обычную функцию, массивные временные переменные/буферы выделяйте в стеке, и вызывайте их все поочереди(и/или по условию) и получите много задач, "параллельно" выполняющихся (находящихся в разной стадии исполнения), плюс оптимальное распределение памяти.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jul 28 2009, 01:55
Сообщение #17


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(defunct @ Jul 28 2009, 04:33) *
Дайте каждой задаче static контекст с которым она работает, оформите как обычную функцию, и вызывайте их все поочереди(и/или по условию) и получите много задач, 

Контекст в виде структуры с передачей указателя на него - получите возможность параллельного исполнения одинаковых задач.
Go to the top of the page
 
+Quote Post
Zlumd
сообщение Jul 28 2009, 06:01
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 12-04-05
Из: Новосибирск
Пользователь №: 4 057



Цитата(defunct @ Jul 28 2009, 08:33) *
Как не крути а процессор один, и для него любая программа будет одной задачей.
Вопрос в абстрагировании. Ниже приведено две реализации одного и того же:
1)
Код
task()
{
   while( true)
   {
       wait_sema( sema_x);
       do_stuff();
   }
}


2)
Код
task()
{
   if ( sema_x)
      do_stuff();
}


Пусть памяти всего 1KB, и есть 3 таска. Во втором варианте каждый таск может запросто взять и пользовать например 512 байт под временный буфер, в первом же 3x512B > 1KB и приехали.
Так очень неудобно код писать. Что делать если хочется посидеть в do_stuff() примерно минуту ?
Цитата(defunct @ Jul 28 2009, 08:33) *
Дайте каждой задаче static контекст с которым она работает, оформите как обычную функцию, массивные временные переменные/буферы выделяйте в стеке, и вызывайте их все поочереди(и/или по условию) и получите много задач, "параллельно" выполняющихся (находящихся в разной стадии исполнения), плюс оптимальное распределение памяти.
Static - это необоснованный расход памяти.
Вот пример:
Код
Thread1()
{
func1();
func2();
func3();
func4();
func5();
func6();
func7();
func8();
}

Пусть в каждой фунции func1...func8 есть локальные переменные по 100 байт в каждой. Если все staticами объявить, то Thread1 800 байт памяти отъест, если auto - то всего 100 байт.

Может быть у нас терминология не совпадает? Я так понимаю, что задачи в вытесняющей ОС - это эквивалент Thread в программировании под Windows. А задачи в кооперативной ОС - это эквивалент Fiber. Я правильно понимаю?
Go to the top of the page
 
+Quote Post
amaora
сообщение Jul 28 2009, 07:43
Сообщение #19


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



Цитата(_Pasha @ Jul 27 2009, 20:54) *
Имхо, это шаг в сторону. Жизнеспособны в этом случае только варианты написания прерываний либо на чистом Си, либо на чистом асме. Остальное - полумеры, рано или поздно кривизна такого подхода себя обнаружит.

С этим согласен, а пример не очень понятный.

Цитата(defunct @ Jul 28 2009, 05:33) *
Вопрос в абстрагировании. Ниже приведено две реализации одного и того же:
...


Во первых если задаче надо так много памяти то очень вероятно, что она долго не будет возвращать управление системе. Во вторых если в системе много ввода/вывода, то что регулярно делать if (data_ready) do_stuff() ? не лучше ли wait_for_event() который блокирует задачу (выводит из планирования), а потом в прерывании она снова ставится в очередь. Так и код проще выглядит.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 28 2009, 23:02
Сообщение #20


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Zlumd @ Jul 28 2009, 09:01) *
Так очень неудобно код писать. Что делать если хочется посидеть в do_stuff() примерно минуту ?

Например сделать свою реализацию ks_wait() / ks_yeild() - которая будет запускать оставшиеся задачи прямо из текущей.
Есть конечно и другой вариант, - разбить do_stuff() на две части, и запускать вторую часть через минуту после первой.

Цитата
Static - это необоснованный расход памяти.

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

Цитата
Пусть в каждой фунции func1...func8 есть локальные переменные по 100 байт в каждой. Если все staticами объявить, то Thread1 800 байт памяти отъест, если auto - то всего 100 байт.

Не нужно бездумно объявлять все статиками. Делайте статиком только, то что должно быть статиком.

Например задача обработки принятого пакета данных - вырождается в
1. вынуть пакет из очереди,
2. обработать
3. засунуть в другую очередь.
4. Гото 1.
Сколько же нужно данных хранить статически для этой задачи? Помоему очевидно, если обеспечить непрерывное выполнение с п.1. до п.3. то статически хранить потребуется всего лишь два указателя на входную и выходную очереди.

Цитата
Может быть у нас терминология не совпадает? Я так понимаю, что задачи в вытесняющей ОС - это эквивалент Thread в программировании под Windows. А задачи в кооперативной ОС - это эквивалент Fiber. Я правильно понимаю?

И да и нет. Насчет первого утверждения - сравнение Thread с таском вытесняющей ОС подходящее.

Что же касается сравнения с Fiber в кооперативной ОС, ну не совсем оно то, хотя близко:

1. Никто не заставляет App управлять процессом, процессом запуска (schedule'ом) может заниматься ядро ОС, задача лишь обязана вернуть управление этому ядру -
либо нативно - выход из функции, либо непосредственным вызовом соответствующей системной функции.
2. Никто не заставляет наделять задачу в кооперативной ОС своим стеком. В связи с тем, что задача сама отдает управление ОС когда ей удобно, - все задачи могут ужиться с одним общим стеком.

Цитата(amaora @ Jul 28 2009, 10:43) *
Во первых если задаче надо так много памяти то очень вероятно, что она долго не будет возвращать управление системе.

Почему же, вот примеры где может потребоваться большой буфер, но не нужно много времени:

- банальный ping
- чтение/запись внешней флешки
- обработка модбас пакета

и т.д. все где имеет место запрос-ответ.

Цитата
Во вторых если в системе много ввода/вывода, то что регулярно делать if (data_ready) do_stuff() ? не лучше ли wait_for_event() который блокирует задачу (выводит из планирования), а потом в прерывании она снова ставится в очередь. Так и код проще выглядит.

Бесспорно так лучше, абсолютно согласен.
Но это же концепции не меняет, соответвующий if просто уйдет "в недра" планировщика, а задача будет состоять из одного только do_stuff().

ks_run( do_stuff, &do_stuff_context, <event_id>, <timeout> );
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jul 29 2009, 10:32
Сообщение #21


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(amaora @ Jul 28 2009, 10:43) *
С этим согласен, а пример не очень понятный.

Когда в кооперативной многозадачке изнутри таска надо отдать управление, вызывается system()

Ранжирование задач по приоритету - чаще всего достаточная мера для исключения рекурсивного вызова задачи , которая в данный момент может отдать управление. Если же есть перекрестные вызовы внутри задач одного приоритета, приходится в каждой задаче городить семафор.
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th June 2025 - 10:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.015 секунд с 7
ELECTRONIX ©2004-2016