Каждый метод компонента в OpenComputers характеризуется его прямотой: есть прямые методы, а есть непрямые. Не раз в ирке разъяснял разницу. Сейчас расскажу и вам.
Предположения:
- Текущая версия мода — 1.7.5.
- Вы собирали опенкомпьютер.
- Вы знаете, кто такой компонент, что у него за методы и как их вызвать.
С непрямыми вызовами всё просто. Они уводят компьютер в сон на тик. Всегда, при любом условии, даже в случае ошибки, после вызова непрямого метода компьютер до следующего тика работать не будет.
Прямые вызовы такого ограничения не имеют. Один такой вызов может занимать произвольное количество времени. Зависит это от бюджета вызовов.
У компьютеров OC есть бюджет вызовов. Это скрытая безразмерная величина. Каждый тик она сбрасывается до определённого значения. Определено оно так:
- Сначала смотрим на процессор в компьютере. Точнее, на уровень: T1 соответствует 0.5, T2 — 1.0, T3 — 1.5.
- Затем на каждую из планок памяти. T1 или T1.5 — это 0.5, T2 или T2.5 — 1.0, T3 или T3.5 — 1.5.
- Получаем несколько чисел. Суммируем, делим на количество — находим тем самым среднее арифметическое, которое и будет максимальным бюджетом вызовов.
Практикум:
- T2 процессор → 1.0
- Планка T2.5 → 1.0
- Планка T3.5 → 1.5
- Бюджет вызовов: (1.0 + 1.0 + 1.5) / 3 ≈ 1.167.
Пример второй:
- Т3 процессор → 1.5
- Планки T3.5 → 1.5, 1.5, 1.5
- Планка T2.5 → 1.0
- Бюджет вызовов: (1.5 + 1.5 + 1.5 + 1.5 + 1.0) / 5 = 1.4.
Достаточно.
Каждый прямой вызов расходует этот бюджет. По умолчанию — ровно одну тысячную его. Самые последние дев-билды мода делают прямые вызовы по умолчанию абсолютно бесплатными. Когда бюджет уходит в минус, компьютер принудительно спит до следующего тика.
Определяет прямоту метода разработчик. Для создания метода в коде мода используется аннотация li.cil.oc.api.machine.Callback. Примерно так (метод hologram.get):
@Callback(direct = true, doc = """function(x:number, y:number, z:number):number -- Returns the value for the specified voxel.""") def get(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { ... }
Если мы видим здесь direct = true, то это абсолютно точно прямой вызов. Если direct = false или отсутствует, то вызов непрямой.
У метода может быть кастомная стоимость вызова. Не 0.001. У дата-карточки такое особенно. Пример (data.inflate):
@Callback(direct = true, limit = 4, doc = """function(data:string):string -- Applies inflate decompression to the data.""") def inflate(context: Context, args: Arguments): Array[AnyRef] = { ... }
limit = 4 читать как "потребляю 1/4 бюджета при вызове". Для сервера выше это 5 вызовов в тик. Недурно.
У видеокарты всё сложно. Вообще, она тоже ограничивает ярость использования через бюджет вызовов. Потому на Т3-комплекте работать будет быстрее. Но количество потребляемого бюджета также зависит и от уровня видеокарточки. Для OC 1.7.5 распределение такое:
Операция | Стоимость | ||
---|---|---|---|
T1 GPU | T2 GPU | T3 GPU | |
setBackground
|
1/32 | 1/64 | 1/128 |
setForeground
|
1/32 | 1/64 | 1/128 |
setPaletteColor
|
1/2 | 1/8 | 1/16 |
set
|
1/64 | 1/128 | 1/256 |
copy
|
1/16 | 1/32 | 1/64 |
fill
|
1/32 | 1/64 | 1/128 |
Поэтому максимально можно вызвать 384 сета в тик.
Чтобы программно определить прямоту методов, есть функция component.methods(addr). Отдаём ей полный адрес компонента, получаем таблицу. В ключах имена методов, в значениях их прямота.
Или же можно воспользоваться этой таблицей. Она включает все методы всех компонентов, которые есть в OpenComputers.
И наконец, размер бюджета можно сменить в конфиге. Опция budgetCosts занимается именно этим.
- 9
- 1
- 2
3 комментария
Рекомендуемые комментарии