mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-25 05:51:56 +01:00
MC Performance Tweaks (#3621)
Ports some StonedMC performance tweaks from /tg/, should reduce the amount of fighting between BYOND sleeps and the MC.
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
#include "code\__defines\subsystem-defines.dm"
|
||||
#include "code\__defines\subsystem-priority.dm"
|
||||
#include "code\__defines\targeting.dm"
|
||||
#include "code\__defines\time.dm"
|
||||
#include "code\__defines\turfs.dm"
|
||||
#include "code\__defines\ZAS.dm"
|
||||
#include "code\_helpers\area_movement.dm"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#define TICK_LIMIT_RUNNING 80
|
||||
#define TICK_LIMIT_TO_RUN 78
|
||||
#define TICK_LIMIT_TO_RUN 70
|
||||
#define TICK_LIMIT_MC 70
|
||||
#define TICK_LIMIT_MC_INIT config.mc_init_tick_limit
|
||||
#define TICK_LIMIT_MC_INIT_DEFAULT 98
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#define SECOND *10
|
||||
#define SECONDS *10
|
||||
|
||||
#define MINUTE *600
|
||||
#define MINUTES *600
|
||||
|
||||
#define HOUR *36000
|
||||
#define HOURS *36000
|
||||
|
||||
#define DAY *864000
|
||||
#define DAYS *864000
|
||||
|
||||
|
||||
#define TICKS *world.tick_lag
|
||||
|
||||
#define DS2TICKS(DS) (DS/world.tick_lag)
|
||||
|
||||
#define TICKS2DS(T) (T TICKS)
|
||||
@@ -28,8 +28,8 @@
|
||||
/proc/Floor(x)
|
||||
return round(x)
|
||||
|
||||
/proc/Ceiling(x)
|
||||
return -round(-x)
|
||||
/proc/Ceiling(x, y=1)
|
||||
return -round(-x / y) * y
|
||||
|
||||
// Greatest Common Divisor: Euclid's algorithm.
|
||||
/proc/Gcd(a, b)
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
#define SECOND *10
|
||||
#define SECONDS *10
|
||||
|
||||
#define MINUTE *600
|
||||
#define MINUTES *600
|
||||
|
||||
#define HOUR *36000
|
||||
#define HOURS *36000
|
||||
|
||||
#define DAY *864000
|
||||
#define DAYS *864000
|
||||
|
||||
var/roundstart_hour = 0
|
||||
var/round_start_time
|
||||
|
||||
|
||||
@@ -664,7 +664,7 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
. = 1
|
||||
|
||||
while (world.time < endtime)
|
||||
stoplag()
|
||||
stoplag(1)
|
||||
if (progbar)
|
||||
progbar.update(world.time - starttime)
|
||||
|
||||
@@ -704,7 +704,7 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
. = 1
|
||||
|
||||
while (world.time < endtime)
|
||||
stoplag()
|
||||
stoplag(1)
|
||||
if (progbar)
|
||||
progbar.update(world.time - starttime)
|
||||
|
||||
@@ -1088,19 +1088,22 @@ var/list/wall_items = typecacheof(list(
|
||||
|
||||
//Increases delay as the server gets more overloaded,
|
||||
//as sleeps aren't cheap and sleeping only to wake up and sleep again is wasteful
|
||||
#define DELTA_CALC max(((max(world.tick_usage, world.cpu) / 100) * max(Master.sleep_delta,1)), 1)
|
||||
#define DELTA_CALC max(((max(world.tick_usage, world.cpu) / 100) * max(Master.sleep_delta-1,1)), 1)
|
||||
|
||||
/proc/stoplag()
|
||||
/proc/stoplag(initial_delay)
|
||||
// If we're initializing, our tick limit might be over 100 (testing config), but stoplag() penalizes procs that go over.
|
||||
// Unfortunately, this penalty slows down init a *lot*. So, we disable it during boot and lobby, when relatively few things should be calling this.
|
||||
if (!Master || Master.initializing || !Master.round_started)
|
||||
sleep(world.tick_lag)
|
||||
return 1
|
||||
|
||||
if (!initial_delay)
|
||||
initial_delay = world.tick_lag
|
||||
|
||||
. = 0
|
||||
var/i = 1
|
||||
var/i = DS2TICKS(initial_delay)
|
||||
do
|
||||
. += round(i*DELTA_CALC)
|
||||
. += Ceiling(i*DELTA_CALC)
|
||||
sleep(i*world.tick_lag*DELTA_CALC)
|
||||
i *= 2
|
||||
while (world.tick_usage > min(TICK_LIMIT_TO_RUN, CURRENT_TICKLIMIT))
|
||||
|
||||
@@ -31,7 +31,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
var/init_time
|
||||
var/tickdrift = 0
|
||||
|
||||
var/sleep_delta
|
||||
var/sleep_delta = 1
|
||||
|
||||
var/make_runtime = 0
|
||||
|
||||
@@ -266,33 +266,40 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
|
||||
iteration = 1
|
||||
var/error_level = 0
|
||||
var/sleep_delta = 0
|
||||
var/sleep_delta = 1
|
||||
var/list/subsystems_to_check
|
||||
//the actual loop.
|
||||
while (1)
|
||||
tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, (((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag)))
|
||||
var/starting_tick_usage = world.tick_usage
|
||||
if (processing <= 0)
|
||||
CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
sleep(10)
|
||||
continue
|
||||
|
||||
//if there are mutiple sleeping procs running before us hogging the cpu, we have to run later
|
||||
// because sleeps are processed in the order received, so longer sleeps are more likely to run first
|
||||
if (world.tick_usage > TICK_LIMIT_MC)
|
||||
sleep_delta += 2
|
||||
CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING - (TICK_LIMIT_RUNNING * 0.5)
|
||||
sleep(world.tick_lag * (processing + sleep_delta))
|
||||
//Anti-tick-contention heuristics:
|
||||
//if there are mutiple sleeping procs running before us hogging the cpu, we have to run later.
|
||||
// (because sleeps are processed in the order received, longer sleeps are more likely to run first)
|
||||
if (starting_tick_usage > TICK_LIMIT_MC)
|
||||
sleep_delta *= 2
|
||||
CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING * 0.5
|
||||
sleep(world.tick_lag * (processing * sleep_delta))
|
||||
continue
|
||||
|
||||
sleep_delta = MC_AVERAGE_FAST(sleep_delta, 0)
|
||||
if (last_run + (world.tick_lag * processing) > world.time)
|
||||
sleep_delta += 1
|
||||
if (world.tick_usage > (TICK_LIMIT_MC*0.5))
|
||||
//Byond resumed us late. assume it might have to do the same next tick
|
||||
if (last_run + Ceiling(world.tick_lag * (processing * sleep_delta), world.tick_lag) < world.time)
|
||||
sleep_delta += 1
|
||||
|
||||
sleep_delta = MC_AVERAGE_FAST(sleep_delta, 1) //decay sleep_delta
|
||||
|
||||
if (starting_tick_usage > (TICK_LIMIT_MC*0.75)) //we ran 3/4 of the way into the tick
|
||||
sleep_delta += 1
|
||||
|
||||
// debug
|
||||
if (make_runtime)
|
||||
var/datum/controller/subsystem/SS
|
||||
SS.can_fire = 0
|
||||
|
||||
if (!Failsafe || (Failsafe.processing_interval > 0 && (Failsafe.lasttick+(Failsafe.processing_interval*5)) < world.time))
|
||||
new/datum/controller/failsafe() // (re)Start the failsafe.
|
||||
if (!queue_head || !(iteration % 3))
|
||||
@@ -332,10 +339,11 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
iteration++
|
||||
last_run = world.time
|
||||
src.sleep_delta = MC_AVERAGE_FAST(src.sleep_delta, sleep_delta)
|
||||
CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING - (TICK_LIMIT_RUNNING * 0.25) //reserve the tail 1/4 of the next tick for the mc.
|
||||
sleep(world.tick_lag * (processing + sleep_delta))
|
||||
|
||||
CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
if (processing * sleep_delta <= world.tick_lag)
|
||||
CURRENT_TICKLIMIT -= (TICK_LIMIT_RUNNING)
|
||||
|
||||
sleep(world.tick_lag * (processing * sleep_delta))
|
||||
|
||||
|
||||
// This is what decides if something should run.
|
||||
|
||||
@@ -660,5 +660,4 @@
|
||||
if (holder)
|
||||
sleep(1)
|
||||
else
|
||||
sleep(5)
|
||||
stoplag()
|
||||
stoplag(5)
|
||||
|
||||
Reference in New Issue
Block a user