Перейти к содержимому
fantomas

Cynosure - настоящий параллелизм для opencomputers

Рекомендуемые сообщения

Наверное уже все участники этого форума знают, что в opencomputers невозможено написать операционную систему с настоящей параллелизацией - достаточччно написать и запустить программу

local x = 0
while true do
  x = x + 1
end

и вся система зависнет, а затем компьютер перезагрузится с ошибкой "too long without yielding".

 

Однако, блуждая по просторам основного форума opencomputers, я наткнулся на операционную системуCynosure, которая делает невозможное возможным.В ней приведенная выше программа не приведёт к экстренной перезагрузке, а будет работать, пока её не прервут. Её даже можно запустить в отдельном потоке и параллельно с ней запускать другие программы.

 

Достигается это при помощи вот этого кода, перед запуском любой програмы или вызовом функции load обрабатывающего запускаемый код посредством добавки coroutine yield между всякими двумя действиями.

 

Страницу операционной системы можно найти вот тут, а её ядро тут.

 

Успешного ознакомления!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
root@localhost: /# lua
Lua 5.3  Copyright (C) 1994-2020 Lua.org, PUC-Rio
> while{}do end
too long without yielding
stack traceback:
  [C]: in function 'pcall'
  machine:809: in global 'xpcall'
  /bin/lua.lua:122: in upvalue 'ok'
  mtarfs:/boot/cynosure.lua:2897: in function <mtarfs:/boot/cynosure.lua:2877>
  ...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, fantomas сказал:

Однако, блуждая по просторам основного форума opencomputers, я наткнулся на операционную системуCynosure, которая делает невозможное возможным.

Борьба с ошибкой "too long without yielding" или борьба за параллелизм не являются абсолютными целями. Вопрос всегда в цене этой борьбы.

 

У нас на форуме где-то имеется тема, в которой один из наших товарищей тоже писал многозадачную систему. И одной из идей также было вставлять в разные места программы какой-то сервисный код, который мог бы приостановить выполнение потока. Решение рабочее, но его производительность оставляет желать лучшего. А в реализации с coroutine.yield в каждой итерации цикла и вовсе замедлит выполнение программы раз в 100. То есть, программа будет выполняться в 100 раз дольше, сохраняя ту же нагрузку на игровой сервер. Мне это кажется слишком высокой платой как за параллелизм, так и за возможность забыть об ошибке TLWY. Тем более, TLWY преодолевается и без использования специальной операционной системы.

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я даже нашёл свой старый пост, в котором когда-то обсуждал этот способ решения проблемы:

В 02.09.2017 в 18:23, eu_tomat сказал:

1) Подменить load своей функцией, автоматически расставляющей по всему коду вызовы yielding. Недостатки этого способа в том, что он провоцирует повышенное потребление памяти и процессорного времени, и годится не для любого кода. Достоинство в том, что потенциально он может спасти систему от падения в TLWY из-за одного кривого приложения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@ProgramCrafter А тебе удалось разобраться, как в этой системе создать новый файл или изменить имеющийся? А то мне эта система при любой попытке записи говорит "device is readonly".

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
5 минут назад, eu_tomat сказал:

Как в этой системе создать новый файл или изменить имеющийся?

root@localhost: /# df
      fs      name    total     used     free
f1fff042    OpenOS  2097152   862293  1234859
...
root@localhost: /# mount f1fff042 /mnt
root@localhost: /# cd mnt
root@localhost: /mnt# edit something.lua

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@ProgramCrafter Спасибо. Теперь мне всё ясно. Падает не только сама проблемная программа, но и вся система. Падение по TLWY воспроизводится так:

  • Запускаем программу:
    local count =0
    for i=1,1e8 do
      count = count+1
    end
    print(count/1e6)

     

  • Ограничиваем вычислительные ресурсы сервера
  • Дожидаемся синего экрана с надписью TLWY

То есть, заявленная задача не решена: падает не только приложение, но и вся система. А самое интересное заключается в том, что решение, о котором я недавно рассказывал, к падению не приводит, и при этом раз в 50 меньше нагружает сервер:

В 28.07.2022 в 15:56, eu_tomat сказал:

Единственно верным ориентиром для оценки приближения TLWY является значение os.clock().

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
21 час назад, fantomas сказал:

Наверное уже все участники этого форума знают, что в opencomputers невозможено написать операционную систему с настоящей параллелизацией - достаточччно написать и запустить программу


local x = 0
while true do
  x = x + 1
end

и вся система зависнет, а затем компьютер перезагрузится с ошибкой "too long without yielding".

 

Однако, блуждая по просторам основного форума opencomputers, я наткнулся на операционную системуCynosure, которая делает невозможное возможным.В ней приведенная выше программа не приведёт к экстренной перезагрузке, а будет работать, пока её не прервут. Её даже можно запустить в отдельном потоке и параллельно с ней запускать другие программы.

 

Достигается это при помощи вот этого кода, перед запуском любой програмы или вызовом функции load обрабатывающего запускаемый код посредством добавки coroutine yield между всякими двумя действиями.

 

Страницу операционной системы можно найти вот тут, а её ядро тут.

 

Успешного ознакомления!

 

идея отличная.

наконец-то что-то новенькое в open computers подъехало, да еще и unix-like круто, мне нравиться

но... какой пароль от root? я хочу потыкать ос подобрал, пароль от root: root

после входа в root ос приветствует, а потом too long without yielding....

Изменено пользователем rootmaster

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, rootmaster сказал:

после входа в root ос приветствует, а потом too long without yielding....

Вот прямо сразу после приветствия? Вообще интересно стало.

 

1 час назад, rootmaster сказал:

наконец-то что-то новенькое в open computers подъехало, да еще и unix-like круто, мне нравиться

Unix-like, конечно радует, но производительность в простых циклах очень огорчает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если кому интересно, как я нашёл уязвимость с TLWY:

В Cynosure есть файл /dev/base/load.lua: https://github.com/Ocawesome101/oc-cynosure/blob/dev/base/load.lua

А там есть набор паттернов, которые говорят, куда вставлять yield.

...
  local patterns = {
    --[[
    { "if([ %(])(.-)([ %)])then([ \n])", "if%1%2%3then%4__internal_yield() " },
    { "elseif([ %(])(.-)([ %)])then([ \n])", "elseif%1%2%3then%4__internal_yield() " },
    { "([ \n])else([ \n])", "%1else%2__internal_yield() " },--]]
    { "([%);\n ])do([ \n%(])", "%1do%2__internal_yield() "},
    { "([%);\n ])repeat([ \n%(])", "%1repeat%2__internal_yield() " },
  }
...

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
19 часов назад, ProgramCrafter сказал:

В Cynosure есть файл /dev/base/load.lua: https://github.com/Ocawesome101/oc-cynosure/blob/dev/base/load.lua

Да, автор темы первой же ссылкой указал именно на этот файл.

Я тоже открыл его, но пошёл немного другим путём. Увидел ключевые слова do, repeat, и сразу вспомнил про goto. Обрушил систему этим кодом:

::c::goto c

Правда, чтобы упала и система, надо придушить ресурсы процессу Майнкрафта. Собственно, OpenOS ведёт себя похожим образом: программы вылетают с ошибкой TLWY, но сама OS продолжает работать. Но если эти трудные моменты выпадают на рестарт сервера, то падает и сама система, уже с синим экраном.

 

P.S.: И ещё я забыл добавить, что даже простой цикл вида while true do end, запущенный на заторможенном сервере, тоже рано или поздно уронит систему, если будет работать продолжительное время.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ранее я дал приблизительную оценку производительности:

В 04.08.2022 в 16:34, eu_tomat сказал:

в реализации с coroutine.yield в каждой итерации цикла и вовсе замедлит выполнение программы раз в 100. То есть, программа будет выполняться в 100 раз дольше, сохраняя ту же нагрузку на игровой сервер.

А теперь решил выполнить реальные замеры производительности. Для получения более полной картины требуется провести длинную серию экспериментов, но для начала достаточно и этого.

 

OpenOS:

lua> time=computer.uptime t0=time()for i=1,1e8 do end print(time()-t0)
  1.35
lua> time=os.clock t0=time()for i=1,1e8 do end print(time()-t0)
  1.307

Цикл под Cynosure создаёт более высокую нагрузку на Cpu и поэтому часто обрывается ошибкой TLWY:

lua> time=require"computer".uptime t0=time()for i=1,1e8 do end print(time()-t0)
  -- две первые попытки оборвались ошибкой TLWY
  -- 3-я попытка: 200.45
lua> time=os.clock t0=time()for i=1,1e8 do end print(time()-t0)
  -- 4 первые попытки оборвались ошибкой TLWY
  -- 5-ая попытка: 85.68

Итоги:

  • Среда Cynosure замедляет выполнение пустого цикла в 148 раз по сравнению со средой OpenOS.
  • Выполнение пустого цикла в среде Cynosure снижает среднюю вычислительную нагрузку примерно в 2.26 раза, что вроде бы должно радовать, но это снижение не компенсирует возросшую длительность выполнения цикла.
  • Среда Cynosure увеличивает итоговую вычислительную нагрузку при выполнении пустого цикла в 65 раз по сравнению со средой OpenOS.
  • Не смотря на принятые меры по противодействию TLWY, они не снимают проблему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 05.08.2022 в 14:50, eu_tomat сказал:

Unix-like, конечно радует, но производительность в простых циклах очень огорчает.

которую я не тестил, потому что пишет мол шел, а потом пишет too long without yielding(не blue скрин)

 

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

 

о сейчас удалось попасть в shell, скорее всего это связано с пере заходом в игру, шас потестю

решил сменить моник на третий, и оно опять не хочет заходить в shell....

Изменено пользователем rootmaster

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 часа назад, rootmaster сказал:

которую я не тестил, потому что пишет мол шел, а потом пишет too long without yielding(не blue скрин)

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

 

Иронично, что система, нацеленная на противодействие TLWY, сама не может авторизовать пользователя по причине TLWY.

 

3 часа назад, rootmaster сказал:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

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

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...