From 77e4429b9bc8ef9d1d2791c6665c551895691645 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Thu, 14 Mar 2024 23:01:18 +0900 Subject: perf: optimize memory allocation --- Makefile | 2 +- benchmarks/20240314-2327.log | 4 ++ src/Execution/MemInst.php | 42 ++++++-------------- test.sh | 2 +- traces/20240314-2329.stderr.log | 86 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 33 deletions(-) create mode 100644 benchmarks/20240314-2327.log create mode 100644 traces/20240314-2329.stderr.log diff --git a/Makefile b/Makefile index 7d1cdb4..6ff9576 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ bench: .PHONY: run run: - php -d zend.assertions=-1 -d memory_limit=256M -d opcache.enable_cli=on -d opcache.jit=on -d opcache.jit_buffer_size=1G examples/php-on-wasm/php-wasm.php + php -d zend.assertions=-1 -d memory_limit=512M -d opcache.enable_cli=on -d opcache.jit=on -d opcache.jit_buffer_size=1G examples/php-on-wasm/php-wasm.php .PHONY: test test: diff --git a/benchmarks/20240314-2327.log b/benchmarks/20240314-2327.log new file mode 100644 index 0000000..814c690 --- /dev/null +++ b/benchmarks/20240314-2327.log @@ -0,0 +1,4 @@ +Benchmark 1: make run + Time (mean ± σ): 3.088 s ± 0.049 s [User: 3.021 s, System: 0.067 s] + Range (min … max): 3.041 s … 3.200 s 10 runs + diff --git a/src/Execution/MemInst.php b/src/Execution/MemInst.php index e37bcd0..53414d7 100644 --- a/src/Execution/MemInst.php +++ b/src/Execution/MemInst.php @@ -9,13 +9,11 @@ use function assert; use function chr; use function count; use function ord; +use function strlen; final class MemInst { - /** - * @var list - */ - private array $data; + private string $data; private const PAGE_SIZE = 64 * 1024; @@ -25,12 +23,12 @@ final class MemInst $minSize = $type->limits->min; // @todo hack $minSize *= 8; - $this->data = array_fill(0, $minSize, str_repeat("\0", self::PAGE_SIZE)); + $this->data = str_repeat("\0", $minSize * self::PAGE_SIZE); } public function size(): int { - return count($this->data) * self::PAGE_SIZE; + return strlen($this->data); } /** @@ -56,8 +54,7 @@ final class MemInst if ($this->size() < $ptr) { return null; } - $page = $this->data[intdiv($ptr, self::PAGE_SIZE)]; - $result = unpack('c', $page, $ptr % self::PAGE_SIZE); + $result = unpack('c', $this->data, $ptr); assert($result !== false); $c = $result[1]; assert(-0x80 <= $c && $c <= 0x7F); @@ -72,8 +69,7 @@ final class MemInst if ($this->size() < $ptr) { return null; } - $page = $this->data[intdiv($ptr, self::PAGE_SIZE)]; - $result = unpack('C', $page, $ptr % self::PAGE_SIZE); + $result = unpack('C', $this->data, $ptr); assert($result !== false); $c = $result[1]; assert(0x00 <= $c && $c <= 0xFF); @@ -130,8 +126,7 @@ final class MemInst if ($this->size() < $ptr) { return null; } - $page = $this->data[intdiv($ptr, self::PAGE_SIZE)]; - $result = unpack('c', $page, $ptr % self::PAGE_SIZE); + $result = unpack('c', $this->data, $ptr); assert($result !== false); $c = $result[1]; assert(-0x80 <= $c && $c <= 0x7F); @@ -146,8 +141,7 @@ final class MemInst if ($this->size() < $ptr) { return null; } - $page = $this->data[intdiv($ptr, self::PAGE_SIZE)]; - $result = unpack('C', $page, $ptr % self::PAGE_SIZE); + $result = unpack('C', $this->data, $ptr); assert($result !== false); $c = $result[1]; assert(0x00 <= $c && $c <= 0xFF); @@ -260,8 +254,7 @@ final class MemInst if ($this->size() < $ptr) { return null; } - $page = $this->data[intdiv($ptr, self::PAGE_SIZE)]; - $result = unpack('C', $page, $ptr % self::PAGE_SIZE); + $result = unpack('C', $this->data, $ptr); assert($result !== false); $c = $result[1]; assert(0x00 <= $c && $c <= 0xFF); @@ -277,8 +270,7 @@ final class MemInst if ($this->size() < $ptr) { return false; } - // @phpstan-ignore-next-line - $this->data[intdiv($ptr, self::PAGE_SIZE)][$ptr % self::PAGE_SIZE] = chr($c); + $this->data[$ptr] = chr($c); return true; } @@ -424,18 +416,6 @@ final class MemInst if ($this->size() < $ptr + $len) { return null; } - $buf = ''; - $idx = $ptr % self::PAGE_SIZE; - for ($p = intdiv($ptr, self::PAGE_SIZE); ; $p++) { - $page = $this->data[$p]; - $readLen = min(self::PAGE_SIZE - $idx, $len); - $buf .= substr($page, $idx, $readLen); - $len -= $readLen; - if ($len === 0) { - break; - } - $idx = 0; - } - return $buf; + return substr($this->data, $ptr, $len); } } diff --git a/test.sh b/test.sh index a87065a..23552a8 100644 --- a/test.sh +++ b/test.sh @@ -1,4 +1,4 @@ -result=$(php -d zend.assertions=-1 -d memory_limit=256M -d opcache.enable_cli=on -d opcache.jit=on -d opcache.jit_buffer_size=1G examples/php-on-wasm/php-wasm.php 2>/dev/null) +result=$(php -d zend.assertions=-1 -d memory_limit=512M -d opcache.enable_cli=on -d opcache.jit=on -d opcache.jit_buffer_size=1G examples/php-on-wasm/php-wasm.php 2>/dev/null) if [[ "$result" == 'Hello, World!' ]]; then echo "Test passed" exit 0 diff --git a/traces/20240314-2329.stderr.log b/traces/20240314-2329.stderr.log new file mode 100644 index 0000000..d466331 --- /dev/null +++ b/traces/20240314-2329.stderr.log @@ -0,0 +1,86 @@ +Decoding... +Instantiating... +Executing... + +Exit code: 0 +Memory peak usage: 323143064 + + +i64.rot_l: 6733 1 6733.000000 +i32.rem_u: 7305 1 7305.000000 +i64.eq: 4999 2 2499.500000 +f64.gt: 5540 2 2770.000000 +f64.load: 21272 2 10636.000000 +f64.mul: 25499 2 12749.500000 +f64.add: 6744 4 1686.000000 +f64.convert_i32_s: 7746 4 1936.500000 +i64.sub: 361953 16 22622.062500 +i64.extend_i32_s: 432682 16 27042.625000 +i64.lt_u: 641791 17 37752.411765 +f64.store: 744168 24 31007.000000 +f64.const: 464155 26 17852.115385 +i32.wrap_i64: 379227 32 11850.843750 +i64.eqz: 585563 42 13941.976190 +i64.gt_u: 471056 46 10240.347826 +i64.or: 478944 46 10411.826087 +i64.shl: 709743 47 15100.914894 +i32.le_s: 748959 49 15284.877551 +i64.xor: 471435 62 7603.790323 +i64.ne: 568949 70 8127.842857 +i32.extend8_s: 571592 78 7328.102564 +i32.load16_s: 813987 81 10049.222222 +memory.size: 701997 130 5399.976923 +i32.ge_s: 692009 134 5164.246269 +i32.ctz: 1094624 155 7062.090323 +i64.and: 602053 226 2663.951327 +i64.shr_u: 489889 239 2049.744770 +i32.extend16_s: 1199617 256 4686.003906 +i32.div_u: 1127920 284 3971.549296 +i64.add: 634539 323 1964.517028 +i32.load16_u: 1136275 426 2667.312207 +i64.extend_i32_u: 1249506 592 2110.652027 +i32.gt_s: 1223292 613 1995.582382 +i64.mul: 1275671 842 1515.048694 +i32.store16: 3287890 1998 1645.590591 +i32.lt_s: 2220142 2161 1027.367885 +i32.rot_l: 3532538 2203 1603.512483 +i32.clz: 4060905 5130 791.599415 +br_table: 3369007 6061 555.850025 +i64.const: 3895103 9965 390.878374 +call_indirect: 8815409968 12643 697256.186665 +i64.load: 9421807 12927 728.847142 +drop: 5123431 15033 340.812280 +i32.xor: 12436555 18826 660.605280 +return: 4770944 19633 243.006367 +i32.le_u: 13365637 25404 526.123327 +global.get: 10376406 25951 399.846095 +select: 13704301 29114 470.711719 +i32.ge_u: 16656897 33468 497.696217 +i32.store8: 18854855 42849 440.030222 +loop: 8725293963 44110 197807.616482 +global.set: 17362896 51161 339.377573 +i32.shr_u: 20238266 51699 391.463394 +i32.load8_s: 20337339 54242 374.937115 +i32.sub: 21552487 64081 336.331939 +i32.eq: 24843378 66100 375.845356 +br: 12245021 66911 183.004603 +i32.mul: 24502465 68122 359.685050 +call: 32674053681 70579 462942.995523 +i32.or: 39856224 71541 557.110244 +i32.shl: 36052558 86408 417.236344 +i32.ne: 30718539 92660 331.518875 +i32.lt_u: 38327762 101169 378.848877 +i32.gt_u: 40061428 117828 339.999219 +i32.load8_u: 63571082 159431 398.737272 +i32.eqz: 52743788 198278 266.009280 +i32.and: 101568221 249884 406.461482 +i64.store: 177976102 306534 580.608030 +i32.store: 183780629 362806 506.553445 +local.set: 99181624 439632 225.601467 +i32.load: 220094856 564315 390.021275 +block: 70106961183 723450 96906.436081 +br_if: 152340418 732305 208.028647 +local.tee: 169203732 758661 223.029432 +i32.add: 196169743 812466 241.449787 +i32.const: 261492311 1589717 164.489850 +local.get: 533212586 3135728 170.044272 -- cgit v1.2.3-70-g09d2