From: Rudolf Polzer Date: Mon, 23 Sep 2024 13:02:27 +0000 (+0200) Subject: Remove the `jumpabsolute` member from `mstatement_s`. X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=59e78406357ef49519e0d12927602b534ef56204;p=xonotic%2Fdarkplaces.git Remove the `jumpabsolute` member from `mstatement_s`. This reduces the struct from 20 to 16 bytes, and thus may save some RAM. It also may improve CPU cache behavior by keeping more QC code in L1 and L2 cache, and possibly also improve instruction processing inside the CPU as all statements are aligned the same way. On `srv04`, this speeds up Xonotic's `serverbench` from 58.92s real, 57.72s user to 57.72s real, 56.59s user (median of 25). --- diff --git a/pr_comp.h b/pr_comp.h index f69b6320..7ca0c28a 100644 --- a/pr_comp.h +++ b/pr_comp.h @@ -409,8 +409,7 @@ mfunction_t; typedef struct mstatement_s { opcode_t op; - int operand[3]; // always a global or -1 for unused - int jumpabsolute; // only used by IF, IFNOT, GOTO + int operand[3]; // always a global, or a relative statement offset ([0] for GOTO, [1] for IF/IFNOT), or -1 for unused } mstatement_t; diff --git a/prvm_edict.c b/prvm_edict.c index cc318e99..3d510187 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -2294,19 +2294,17 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data prog->error_cmd("%s: out of bounds IF/IFNOT (statement %d) in %s", __func__, i, prog->name); prog->statements[i].op = op; prog->statements[i].operand[0] = remapglobal(a); - prog->statements[i].operand[1] = -1; + prog->statements[i].operand[1] = b; prog->statements[i].operand[2] = -1; - prog->statements[i].jumpabsolute = i + b; break; case OP_GOTO: a = (short)a; if (a + i < 0 || a + i >= prog->progs_numstatements) prog->error_cmd("%s: out of bounds GOTO (statement %d) in %s", __func__, i, prog->name); prog->statements[i].op = op; - prog->statements[i].operand[0] = -1; + prog->statements[i].operand[0] = a; prog->statements[i].operand[1] = -1; prog->statements[i].operand[2] = -1; - prog->statements[i].jumpabsolute = i + a; break; default: Con_DPrintf("%s: unknown opcode %d at statement %d in %s\n", __func__, (int)op, i, prog->name); @@ -2316,7 +2314,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data prog->statements[i].operand[0] = 0; prog->statements[i].operand[1] = prog->statements[i].operand[2] = op; - prog->statements[i].jumpabsolute = -1; break; case OP_STORE_I: case OP_ADD_I: @@ -2427,7 +2424,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data prog->statements[i].operand[0] = remapglobal(a); prog->statements[i].operand[1] = remapglobal(b); prog->statements[i].operand[2] = remapglobal(c); - prog->statements[i].jumpabsolute = -1; break; // global none global case OP_NOT_F: @@ -2441,7 +2437,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data prog->statements[i].operand[0] = remapglobal(a); prog->statements[i].operand[1] = -1; prog->statements[i].operand[2] = remapglobal(c); - prog->statements[i].jumpabsolute = -1; break; // 2 globals case OP_STOREP_F: @@ -2466,7 +2461,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data prog->statements[i].operand[0] = remapglobal(a); prog->statements[i].operand[1] = remapglobal(b); prog->statements[i].operand[2] = -1; - prog->statements[i].jumpabsolute = -1; break; // 1 global case OP_CALL0: @@ -2493,7 +2487,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data prog->statements[i].operand[0] = remapglobal(a); prog->statements[i].operand[1] = -1; prog->statements[i].operand[2] = -1; - prog->statements[i].jumpabsolute = -1; break; } } diff --git a/prvm_exec.c b/prvm_exec.c index 3c68f6d1..e7f54680 100644 --- a/prvm_exec.c +++ b/prvm_exec.c @@ -332,10 +332,17 @@ static void PRVM_PrintStatement(prvm_prog_t *prog, mstatement_t *s) for ( ; i<10 ; i++) Con_Print(" "); - if (s->operand[0] >= 0) Con_Printf( "%s", PRVM_GlobalString(prog, s->operand[0], valuebuf, sizeof(valuebuf))); - if (s->operand[1] >= 0) Con_Printf(", %s", PRVM_GlobalString(prog, s->operand[1], valuebuf, sizeof(valuebuf))); + if (s->op == OP_GOTO) { + Con_Printf("statement %i", (int)(s - prog->statements) + s->operand[0]); + } else { + if (s->operand[0] >= 0) Con_Printf( "%s", PRVM_GlobalString(prog, s->operand[0], valuebuf, sizeof(valuebuf))); + } + if (s->op == OP_IF || s->op == OP_IFNOT) { + Con_Printf(", statement %i", (int)(s - prog->statements) + s->operand[1]); + } else { + if (s->operand[1] >= 0) Con_Printf(", %s", PRVM_GlobalString(prog, s->operand[1], valuebuf, sizeof(valuebuf))); + } if (s->operand[2] >= 0) Con_Printf(", %s", PRVM_GlobalString(prog, s->operand[2], valuebuf, sizeof(valuebuf))); - if (s->jumpabsolute >= 0) Con_Printf(", statement %i", s->jumpabsolute); Con_Print("\n"); } diff --git a/prvm_execprogram.h b/prvm_execprogram.h index 2a70bfc8..34dd8d29 100644 --- a/prvm_execprogram.h +++ b/prvm_execprogram.h @@ -637,7 +637,7 @@ int i; // and entity, string, field values can never have that value { ADVANCE_PROFILE_BEFORE_JUMP(); - st = cached_statements + st->jumpabsolute - 1; // offset the st++ + st += st->operand[1] - 1; // offset the st++ startst = st; // no bounds check needed, it is done when loading progs if (++jumpcount == 10000000 && prvm_runawaycheck) @@ -657,7 +657,7 @@ int i; // and entity, string, field values can never have that value { ADVANCE_PROFILE_BEFORE_JUMP(); - st = cached_statements + st->jumpabsolute - 1; // offset the st++ + st += st->operand[1] - 1; // offset the st++ startst = st; // no bounds check needed, it is done when loading progs if (++jumpcount == 10000000 && prvm_runawaycheck) @@ -671,7 +671,7 @@ int i; HANDLE_OPCODE(OP_GOTO): ADVANCE_PROFILE_BEFORE_JUMP(); - st = cached_statements + st->jumpabsolute - 1; // offset the st++ + st += st->operand[0] - 1; // offset the st++ startst = st; // no bounds check needed, it is done when loading progs if (++jumpcount == 10000000 && prvm_runawaycheck)