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

eu_tomat

Модераторы
  • Публикации

    2 666
  • Зарегистрирован

  • Посещение

  • Победитель дней

    331

Все публикации пользователя eu_tomat

  1. Это вряд ли. Скорее всего, в полном соответствии с тиками. Я могу ошибаться, но склоняюсь к тому, что лагает исполнение кода Lua в OpenComputers. Причём, слово "лагает" я использую в изначальном его смысле, когда ожидаемое событие приходит с задержкой. Боюсь сейчас соврать, результатов экспериментов под рукой нет, но, насколько я помню, обращение к периферии вместо одного тика иногда требует двух тиков, а в моменты сильного снижения TPS задержка доходила и до 5 тиков. И это, возможно, не предел. Все мои эксперименты подтверждали абсолютно детерминированную работу реакторов. Случайности возникают вокруг реактора: случайным образом поджигаются блоки или превращаются в лаву. Блоки обшивки ЖЯР тоже могут выгореть случайным образом. Но компоненты реактора взаимодействуют друг с другом абсолютно предсказуемым образом. Я плохо понял о чём здесь идёт речь. Чем плоха реализация os.sleep, если не вешать на него тяжёлые обработчики событий? Работа os.sleep основана на вызовах computer.pullSignal, другого вменяемого способа для создания задержек нет. Чтобы понять, насколько хорошим будет результат при фиксированных задержках, нужен ряд экспериментов и правильно интерпретация их результатов: Надо всё-таки понять, в каком месте возникает джиттер: на этапе тиков реактора, или на этапе получения ответа от транспозера. Надо как-то определить теоретически максимально возможный размер джиттера. Надо проверить, нет ли дрейфа циклов ректора при выгрузке-загрузке чанков. Пока ответы на эти вопросы не получены, приходится подстраховывать частой проверкой состояния какого-либо из слотов реактора. Необязательно выполнять проверку каждый тик. Время замены очередного отражателя известно с точностью до секунды. Поэтому уменьшаем это время на одну секунду и смело спим. А потом начинаем каждый тик проверять точный момент критического износа отражателя. Как только поймали момент, заменяем отражатель.
  2. 13*0.05 = 0.65 секунд на проверку. Плюс 2*0.05 = 0.1 секунд на замену одного отражателя. Вполне реально. Но при сильном снижении TPS сервера можно и не успеть произвести замену. Особенно, если требуется заменить более одного отражателя за раз. Есть более быстрый способ контроля, но он потребует усложнения алгоритма. Реактор не является чёрным ящиком, и его текущее состояние поддаётся вычислению из предыдущих. В большинстве случаев даже не требуется писать эмулятор реактора. Достаточно вычислять лишь ключевые значения. Что для этого нужно знать? Во-первых, компьютеры OpenComputers определяют время с точностью до тика. Реакторы и все его компоненты одномоментно изменяют своё состояние один раз в 20 тиков. Во время лагов интервалы между реакторными тиками могут становиться неравномерными, сжимаясь и расширяясь на несколько майнкрафтовских тиков. Но в одном можно быть уверенным: если в какой-то момент была зарегистрирована смена состояния одного из компонентов реактора, то изменилось и состояние других компонентов, если схема вообще предполагает изменение их состояния. Во-вторых, некоторые из малых изменений состояний реакторных компонентов невозможно остследить по причине слегка кривой арифметики. Поэтому очередной реакторный тик не всегда удаётся отследить посредством проверки, например, прочности MOX-сборки, и тем более, урановой сборки. Но в нашей схеме отражатели сгорают быстро, их прочность меняется каждый реакторный тик на очень большие величины, которые невозможно скрыть даже имеющейся арифметикой. В-третьих, в зависимости от применённой схемы можно посчитать точное время работы любого из компонентов реактора. Это позволяет заранее составить график плановой замены компонентов. Для максимальной защиты реактора от лагов сервера график замены компонентов должен быть по возможности равномерным. Знание этих механик позволяет вычислять состояние всех компонентов реактора, ориентируясь по состоянию лишь одного из них, экономить драгоценные тики и повышать устойчивость микроконтроля. А пр аккуратном программировании можно даже снизить нагрузку на сервер.
  3. Категоричное утверждение. Рационально будет или нет, всецело зависит от используемого алгоритма и размера отдельной итерации. А в теме эти параметры никак не обозначены.
  4. Сигнал случайно вытащить можем. Поэтому, если важно не терять сигналы, то потребуется написать обработчик. Если пропуск сигналов критичен, то проверка сигналов обязательна в любом случае, т.к. очередь сигналов ограничена и может быть переполнена. yield, скорее всего, нужно вызвать с параметром времени ожидания yield(0), или же ждать сигнала. Как в этом случае обрабатывать само событие, я не знаю, не пробовал.
  5. Выполнение computer.pullSignal(0) обеспечит минимальную уступку времени.
  6. Интересное дополнение, хотя и спорное. Во-первых, проще было бы не втискиваться в рамки стандартной утилиты, а написать свою, специально предназначенную для записи на ленту и чтения с неё файлов с произвольными данными. И ориентироваться не по нулевому байту, а по размеру файла, заданному в заголовке. Во-вторых, непонятна применимость подобного подхода. Обычные жёсткие диски по причине их малого объёма не позволяют задействовать весь потенциал ленты. Думаю, полезной была бы архивная файловая система с ограниченными функциями: произвольное чтение любого из уже записанных на ленту файлов и дописывание в конец ленты новых файлов.
  7. @norecord Сканирование столбцами было единственным вариантом в ранних версиях OpenComputers. Но позже появилась возможность сканирования произвольной области общим объёмом не более 64 блоков. Это позволяет ускорить сканирование плоской местности в 64 раза. Сейчас программа выполняет 1089 сканирований за 55 секунд, хотя достаточно лишь 18 сканирований и 1 секунды. Правда, потребуется усложнить код.
  8. Это по информации от @Alex проясняется. А что хочет автор вопроса, остаётся лишь предполагать.
  9. А там, это где? Индикаторы сами по себе не сигнализируют о покупке и продаже. Они преобразуют сырые данные котировок с целью выделить на графике нужные нам особенности движения цен. Зная смысл значений, вычисляемых индикатором, трейдер определяет условия совершения покупок и продаж. Со смысла я и предлагаю начать. Что вычисляет этот индикатор? И ещё раз спрошу: в какой среде должен работать этот индикатор?
  10. Ещё раз спрошу: в какой среде должен исполняться этот код на языке Lua? Хорошо, Xsrar это индикатор. Объясни теперь, что показывает индикатор Xsar, и по какому алгоритму торгует Судак.
  11. Автор куда-то пропал, и спросить теперь не у кого. Но чтобы не вводить в заблуждение наших читателей, припишу "QUIK" к его вопросам. И на другой его вопрос о торговых роботах оставлю ссылку.
  12. eu_tomat

    Оффтоп

    Часть моих вопросов ты игнорируешь, на другую часть даёшь размытые, общие формулировки. Конкретики маловато. Да ещё и свои ответы зачем-то закинул в мою цитату. Как это воспринимать читателям? Ну, хорошо – имеешь право. Разговоры ни о чём я перемещаю в тему оффтопа. В моей же теме я не хочу постов с обилием общих фраз, метафор и подобного. Мне хочется конкретики с минимумом слов. Если будут конкретные идеи по теме – добро пожаловать. Если хочешь повторить мой опыт, предлагаю создать собственную тему и развивать её. Я не только не возражаю против этого, но даже поддерживаю. В своей теме ты можешь писать, как удобно лично тебе, и определять собственный формат. И это, кстати, даже хорошо. Будет пример для сравнения. Возможно, я тоже позаимствую какие-то из твоих удачных приёмов. Если не сможешь самостоятельно найти ответы на возникающие вопросы – спрашивай. Если найдёшь подходящий раздел на форуме, то лучше спрашивать в предназначенном для этого разделе вопросов. Если это будут какие-то специфические вопросы по изучаемой тобой теме, то можешь спрашивать прямо в ней. И не обязательно отвечу именно я. У нас есть ребята, гораздо более глубоко разбирающиеся в тех или иных вопросах. И главное, ты что-то делай. Люди охотнее помогают тем, кто уже сам проделал значительную часть работы.
  13. @Gendalf_Svetliy Привет! Я рад, что мой опыт вдохновляет других людей на развитие. Обычно я не только не против, но и, как правило, за. Пропуском входа на лодку будут твои ответы на мои вопросы. Что ты называешь моей лодкой? И что называешь запрыгиванием в неё? На твой взгляд, в чём заключается мой метод? В чём его главные достоинства? Что он даёт читателю? Что даёт писателю? Какие из моих действий ты считаешь наиболее достойными для подражания? В чём именно тебе требуется моя поддержка? И какие из моих навыков ты хочешь закрепить?
  14. Какой смысл вкладывается в слово "объединить"? Есть два робота, иногда они могут принимать сходные решения по сделкам, а иногда противоположные. Что требуется делать в каждом конкретном случае? Применительно к биржевым роботам, код – это последнее, чем стоит заниматься. Какой язык там будет использоваться в конечном итоге: QLua или MQL – не играет значительной роли. Сначала следует проработать логику. Нужно описать логику одного робота, затем описать логику другого, и в конце концов определить логику взаимодействия этих двух роботов. И тогда уже станет понятно, как объединить код этих двух роботов. @DESHLI Опиши своими словами, как каждый из этих двух роботов принимает решение о времени и размере сделки. А потом вместе подумаем, как можно объединить их логику. И если получится что-то внятное, то и про код подумаем.
  15. @DESHLI Если речь идёт про код из темы про торговых роботов, то ind (он же index) это индекс котировки торгуемого инструмента. И это подтверждается кодом со скриншота. Для начального индекса выполняется инициализация различных индикаторов: верхний и нижний уровни свечей (H,L), скользящие средние, индикаторы волатильности, параболики и прочее. А по мере поступления новых котировок происходит вычисление индикаторов. Сама же функция, скорее всего, является более сложным индикатором, основанном на комбинации более простых.
  16. @DESHLI Просьба на будущее: Любой код оформлять соответствующим тегом. Длинный код прятать спойлер. И текущая просьба: проверить, правильно ли я перенёс код в теги, не потерялось ли там что-нибудь. @DESHLI Кстати, предупреждать надо. У нас на форуме словосочетание "торговый робот" несёт иной смысл. В какой среде эти роботы запускаются?
  17. @DESHLI По этому скриншоту тоже ничего не понять, нужен полный код функции. Как и сказал @serafim , это какой-то индекс. Но на основании одного лишь приведённого фрагмента сложно говорить о назначении этого индекса. Допускаю, что и полного текста функции тоже окажется недостаточно, и для полной ясности потребуется код всей программы. И даже полный код программы может не дать полной ясности, и тогда могут потребоваться объяснения, какую задачу должен решать этот код, и в самом ли деле решает, или это черновой набросок. Если программа не секретная, то предлагаю выложить её полный код. Может быть, тогда что-то прояснится.
  18. Да, можно и так. Но я хотел научиться собирать через горячие клавиши IDE, что у меня долго не получалось. К этому моменту я вроде бы осилил сборку, но сам не понял, почему получилось сейчас, и почему не получалось до этого. Я эти свои гуишные метания даже задокументировать нормально не смог. О чём-то сделанном я забыл записать, что-то я записал, и даже сделал, но, возможно промахнулся кликом. Чтобы какой-то внятный отчёт выложить, надо будет удалить все рабочие папки и заново всё проделать. С консольными командами всё проще и понятнее: есть команда и есть её вывод. Также сохраняется и последовательность команд, благодаря чему нет нужды постоянно фиксировать всю последовательность действий. И текст из консоли легко копируется в мой документ.
  19. В этом-то и заключались грабли. И усугубились они тем, что текст ошибки никак не указывал на несоответствующую версию Gradle. Уже сижу, разбираюсь. Собрать OC из IDE мне пока не удалось. Я продолжаю наступать на новые грабли. Раздражаюсь, вглядываясь в разные гуишные формочки, расставляя руками какие-то галочки и занимаясь прочим мышкотыканьем. Но пока терплю.
  20. Что за блок? И насколько ближайших?
  21. Много существует этих способов. Например, для экспериментов в креативе я использую TickrateChanger. Очень помогает ускорить отладку программ, работающих с объектами мира. Но есть нюансы. Для достижения высокого TPS требуется иметь быстрый процессор. Если реальный комп не справляется с нагрузкой, то часть тиков пропускается, причём, в неуправляемом порядке. Недавно разработчики OpenComputers слегка модифицировали алгоритм работы GPU. Это тоже позволяет сильно увеличить FPS на экранах без необходимости поднимать TPS. Можешь посмотреть в экспериментальных сборках OpenComputers.
  22. В те времена, когда эта тема была мне интересна, не встречал. Сам я писал визуализатор фрактала Жюлиа на HTML/JavaScript. В полный экран рисовал, но параметры я задавал через поля формы и адресную строку браузера. То есть, на управлении я не заморачивался.
  23. Жаль, что нет кода. В давние времена, когда я интересовался темой процедурной генерации графики, вдохновлялся этим сайтом http://arbuz.uz/x_vernisag.html
  24. Первый опыт компиляции и правок OpenComputers Задача: Собрать мод OpenComputers, проверить его работоспособность в игре, внести небольшие правки в мод и также проверить их работоспособность в игре. Мой путь к решению: Первая страница поисковой выдачи по фразе «opencomputers build mod» не показала ничего интересного для меня. Зато фраза «opencomputers build from source» быстро привела меня на страницу https://ocdoc.cil.li/tutorial:debug_1.7.10 Команды инструкции несколько отличаются от тех, что я применял раньше. Поэтому я задал себе два вопроса: Чем отличается вызов gradlew от gradle? Чем отличается setupDecompWorkspace от setupCIWorkspace? На первый вопрос я ответил неправильно. Из найденной информации я понял, что обёртка gradlew используется для того, чтобы не морочить себе голову отдельной установкой Gradle и всё необходимое устанавливать через скрипт. Но у меня же уже установлен Gradle! Поэтому проще использовать именно его. Ещё не понимая, в чём грабли, я в хаотическом порядке побежал по коммитам, дойдя чуть ли не до начала репозитория. Но gradle упорно выдавал ошибку даже при запуске без параметров: $ gradle ... A problem occurred evaluating root project 'OpenComputers'. > Failed to apply plugin [id 'forge'] > Could not create task of type 'ReobfTask'. Поиск по фразе «gradle Could not create task of type ReobfTask» не дал ничего вразумительного кроме того, что может быть неправильной версия не то Gradle, не то Forge, не то Minecraft, не то JDK. Так я ходил по граблям около двух часов, пытаясь что-то изменить в конфигах Gradle и переходя от коммита к коммиту. Почувствовав усталость, я решил, что зашёл в тупик, и чтобы выйти из него, мне следует взять перерыв, и отдохнув, найти новую точку для приложения усилий. Так я и сделал. Отдохнув, я ещё раз почитал об отличии gradlew от gradle, вспомнил, что встреченная мной ошибка может быть вызвана неправильной версией Gradle, и сразу осознал упущенный мной нюанс: gradlew – не просто обёртка, и позволяет не просто обойтись без установки gradle, а без установки требуемой версии gradle. Проверяю предположение: $ gradle -version Gradle 2.10 $ ./gradlew -version Gradle 5.6.4 Так и есть! Вывод: Для ускорения продвижения в изучении в первый раз следует максимально чётко следовать инструкциям. А уже имея эталонный рабочий вариант, можно смело экспериментировать. Зная, в чём именно я совершил отклонение, можно быстрее находить и причину неудачи тоже. Я быстро отработал ту часть инструкции, которая не касалась использования IDE, нашёл файл свежесобранного мода, переместил его в каталог с остальными модами и запустил игру: $ git clone https://github.com/MightyPirates/OpenComputers.git $ cd OpenComputers $ ./gradlew setupDecompWorkspace $ ./gradlew build $ find . -name OpenComputers*.jar ./libs/OpenComputers-LuaJ.jar ./libs/OpenComputers-JNLua.jar ./build/libs/OpenComputers-MC1.7.10-1.7.5+f73dd9e-dev.jar ./build/libs/OpenComputers-MC1.7.10-1.7.5+f73dd9e-javadoc.jar ./build/libs/OpenComputers-MC1.7.10-1.7.5+f73dd9e-api.jar ./build/libs/OpenComputers-MC1.7.10-1.7.5+f73dd9e-sources.jar $ mv build/libs/OpenComputers-MC1.7.10-1.7.5+???????-universal.jar ~/.minecraft/mods/OpenComputers-MC1.7.10-1.7.5+test-universal.jar Работает! Отвечая на второй вопрос и вникая в нюансы Gradle, я узнал, что его задачи зависят друг от друга. И если я верно понял, то для сборки мода достаточно лишь скачать репозиторий и запустить сборку мода. Необходимые для этого этапа подзадачи будут выполнены автоматически. Проверяю: Для чистоты эксперимента удаляю папку с модом и пользовательскую папку Gradle: $ rm -rf OpenComputers $ rm -r ~/.gradle И получаю собранный мод минимумом команд: $ git clone https://github.com/MightyPirates/OpenComputers.git $ cd OpenComputers $ ./gradlew build Остаётся лишь перенести мод в каталог с другими модами: $ mv build/libs/OpenComputers-MC1.7.10-1.7.5+???????-universal.jar ~/.minecraft/mods/OpenComputers-MC1.7.10-1.7.5+test-universal.jar С компиляцией и сборкой я разобрался. Теперь пора что-нибудь изменить в моде. Чтобы не выдумывать задачу, я вспоминаю исходную цель. В OpenComputers мне не нравится механика управления нагрузкой от пользовательских скриптов. Что я об этом знаю? Во время длительных вычислений я могу получить ошибку «too long without yielding». Попробую найти эту строку в исходниках: $ grep -ir 'too long without yielding' src/main/resources/assets/opencomputers/lua/machine.lua:local tooLongWithoutYielding = setmetatable({}, { __tostring = function() return "too long without yielding" end}) Удача! Это файл на Lua, и мне сейчас, возможно, не потребуется вникать в Scala. Открываю этот файл первым подвернувшимся под руку редактором: $ nano src/main/resources/assets/opencomputers/lua/machine.lua Ищу, как используется переменная tooLongWithoutYielding. Ошибка с таким исключением генерируется лишь в одном месте, в функции checkDeadline() по результатам проверки computer.realTime() > deadline. Ищу, где и как используется переменная deadline. Стараясь не вникать в детали кода, я нахожу участок, который с наибольшей вероятностью задаёт время, в течение которого пользовательский скрипт может работать без уступки времени: deadline = computer.realTime() + system.timeout(). Лучших вариантов я не вижу, поэтому правлю эту строку. Проверяю выполненные изменения: $ git diff --- a/src/main/resources/assets/opencomputers/lua/machine.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -1486,7 +1486,7 @@ local function main() ... - deadline = computer.realTime() + system.timeout() + deadline = computer.realTime() + 10 --system.timeout() По уже отработанной схеме компилирую мод, переношу его в папку с модами и запускаю игру. Для проверки внесённых в мод изменений я запускаю тестовый скрипт: # lua lua > clock=os.clock t_=clock() pcall(function() while true do end end) t=clock() print(t-t_) 5.000662049 Вроде бы ничего не изменилось. Но я перезагружаю тестовый компик и снова запускаю скрипт. Получаю результат: 9.999750501 Сработало! Подобного поведения можно добиться и банальной правкой конфига, но моя цель заключалась в достижении того же эффекта правкой исходников мода. Результат: Я смог скомпилировать мод OpenComputers, осознал пользу обёртки gradlew, нашёл минимальный набор команд для компиляции, а также внёс работоспособное изменение в мод. Ближайшие планы: Во время решения этой задачи я снова уклонился от использования IDE. Но сейчас я начал серьёзно колебаться, выбирая между двумя направлениями: приступить к поиску оптимального алгоритма управления нагрузкой, или же всё таки освоить работу с IDE хотя бы на базовом уровне.
  25. Однако, что уже сделано? Буду исходить из того, что статья @1Ridav помогла получить список всех найденных цифр с их значениями и позициями на скриншоте. Теперь этот список надо преобразовать в список чисел. Как эти числа расположены на экране? Можно взглянуть на типичный скриншот, с которым придётся работать?
×
×
  • Создать...