Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement an initial version of property caching #1214

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

svaarala
Copy link
Owner

@svaarala svaarala commented Dec 20, 2016

Implement an initial version of property caching where the property cache key is a (generation, object, key) triple. The cache is implemented in GETPROP (the most common property read operation) and the object in the triple is for the starting point of a property lookup. The generation count is a quick way of invalidating the whole cache on any property write or other operation risking cache integrity: entries can be invalidated by a single heap-level generation counter increment without touching the entries themselves. The generation is checked on a cache lookup; no hash chaining is used, and each property lookup hash has only a single slot.

So far this is pretty experimental and some invalidation cases are still missing. The goal is to try to figure out if the approach is workable given all the low level details. Quite possibly some small detail may prevent this from being finished as a viable feature.

Initial results are reasonable however:

  • tests/perf/test-array-read-lenloop.js (whose main point is a for (j = 0; j < arr.length; j++) {...} loop) runs 2.1 seconds from master and 1.5 seconds with caching.
  • tests/perf/test-fib.js runs 7.1 seconds from master and 6.3 seconds with caching.
  • tests/perf/test-assign-proprhs.js runs 3.7 seconds from master and 1.7 seconds with caching.
  • tests/perf/test-prop-read-long-inherit.js runs 6.9 seconds from master and 0.3 seconds with caching. The speedup here is rather unrealistic, as this microbenchmark just demonstrates performance of looking up a long inheritance chain for which caching is (quite obviously) particularly effective.

Tasks:

  • Finalize design
  • Compare to other alternatives like "own property" caching, other cache key/hash models, etc
  • Add config option for feature and property cache size
  • Make invalidation calls macro based (works better in separate sources build)
  • With 64-bit types the generation count rollover might not need to be checked
  • Leave index writes out of caching altogether; must be applied to arrays/typedarrays, but also to all other objects because they may inherit index properties from arrays
  • Debug stats, dump in mark-and-sweep?
  • Test coverage for all invalidation locations; stress test?
  • Assertion coverage for property lookups: when using cached value/location, assert that it's the right one
  • Performance config examples, documentation
  • Releases entry

One simple short term improvement is to allow property cache to store a property location (duk_tval *) and attributes. Property writes can then be processed without doing an ancestor lookup. If only writable properties are cached, no attribute check is needed either.

@svaarala svaarala added this to the v2.1.0 milestone Dec 20, 2016
@svaarala
Copy link
Owner Author

Rough performance testing:

test-add-fastint.js                 : duk.O2  0.65 duk.O2.master  0.66 jerry  2.56
test-add-float.js                   : duk.O2  0.66 duk.O2.master  0.69 jerry  3.88
test-add-nan-fastint.js             : duk.O2  0.77 duk.O2.master  0.74 jerry  3.09
test-add-nan.js                     : duk.O2  0.65 duk.O2.master  0.64 jerry  3.88
test-arith-add.js                   : duk.O2  2.65 duk.O2.master  2.54 jerry 15.39
test-arith-div.js                   : duk.O2  7.30 duk.O2.master  7.22 jerry 19.81
test-arith-mod.js                   : duk.O2  6.71 duk.O2.master  6.56 jerry 23.23
test-arith-mul.js                   : duk.O2  3.89 duk.O2.master  3.48 jerry 15.86
test-arith-sub.js                   : duk.O2  2.72 duk.O2.master  2.73 jerry 15.86
test-array-append.js                : duk.O2  0.54 duk.O2.master  0.53 jerry   n/a
test-array-cons-list.js             : duk.O2  0.85 duk.O2.master  0.93 jerry  2.16
test-array-foreach.js               : duk.O2  2.68 duk.O2.master  2.69 jerry  1.58
test-array-literal.js               : duk.O2  1.68 duk.O2.master  1.64 jerry  0.86
test-array-pop.js                   : duk.O2  2.27 duk.O2.master  2.40 jerry  6.76
test-array-push.js                  : duk.O2  2.60 duk.O2.master  2.75 jerry  3.67
test-array-read-lenloop.js          : duk.O2  1.50 duk.O2.master  2.13 jerry  4.03
test-array-read.js                  : duk.O2  1.78 duk.O2.master  1.74 jerry  5.02
test-array-sort.js                  : duk.O2  3.55 duk.O2.master  3.44 jerry  3.79
test-array-write-length.js          : duk.O2  1.62 duk.O2.master  1.83 jerry  2.49
test-array-write.js                 : duk.O2  1.69 duk.O2.master  1.76 jerry  5.75
test-assign-add.js                  : duk.O2  3.67 duk.O2.master  3.74 jerry 22.73
test-assign-addto-nan.js            : duk.O2  1.29 duk.O2.master  1.23 jerry  5.62
test-assign-addto.js                : duk.O2  3.71 duk.O2.master  3.71 jerry 27.60
test-assign-boolean.js              : duk.O2  4.73 duk.O2.master  4.71 jerry 19.48
test-assign-const-int.js            : duk.O2  2.71 duk.O2.master  2.45 jerry 11.04
test-assign-const-int2.js           : duk.O2  4.85 duk.O2.master  4.76 jerry 11.08
test-assign-const.js                : duk.O2  4.18 duk.O2.master  3.60 jerry 15.66
test-assign-literal.js              : duk.O2  3.77 duk.O2.master  3.74 jerry 21.79
test-assign-proplhs-reg.js          : duk.O2  2.60 duk.O2.master  3.57 jerry  4.87
test-assign-proprhs.js              : duk.O2  1.68 duk.O2.master  3.70 jerry  3.55
test-assign-reg.js                  : duk.O2  2.79 duk.O2.master  2.94 jerry 14.76
test-base64-decode-whitespace.js    : duk.O2  1.91 duk.O2.master  1.87 jerry   n/a
test-base64-decode.js               : duk.O2  1.51 duk.O2.master  1.52 jerry   n/a
test-base64-encode.js               : duk.O2  1.70 duk.O2.master  1.71 jerry   n/a
test-bitwise-ops.js                 : duk.O2  1.88 duk.O2.master  1.84 jerry 21.11
test-break-fast.js                  : duk.O2  1.32 duk.O2.master  1.37 jerry  1.18
test-break-slow.js                  : duk.O2  7.40 duk.O2.master  7.40 jerry  4.21
test-buffer-nodejs-read.js          : duk.O2  2.28 duk.O2.master  2.19 jerry   n/a
test-buffer-nodejs-write.js         : duk.O2  3.02 duk.O2.master  2.99 jerry   n/a
test-buffer-object-read.js          : duk.O2  2.28 duk.O2.master  2.25 jerry   n/a
test-buffer-object-write.js         : duk.O2  3.00 duk.O2.master  3.08 jerry   n/a
test-buffer-plain-read.js           : duk.O2  1.87 duk.O2.master  1.87 jerry   n/a
test-buffer-plain-write.js          : duk.O2  1.79 duk.O2.master  1.76 jerry   n/a
test-call-basic-1.js                : duk.O2  7.67 duk.O2.master  7.63 jerry  9.11
test-call-basic-2.js                : duk.O2  7.74 duk.O2.master  7.72 jerry  8.24
test-call-basic-3.js                : duk.O2  9.68 duk.O2.master  9.75 jerry 14.23
test-call-basic-4.js                : duk.O2 17.76 duk.O2.master 17.27 jerry 35.34
test-call-native.js                 : duk.O2 13.37 duk.O2.master 13.45 jerry  7.70
test-call-prop.js                   : duk.O2  3.81 duk.O2.master  4.83 jerry  4.12
test-call-reg-new.js                : duk.O2  6.60 duk.O2.master  6.78 jerry  3.14
test-call-reg.js                    : duk.O2  2.98 duk.O2.master  3.06 jerry  3.32
test-call-var.js                    : duk.O2  7.48 duk.O2.master  8.39 jerry  3.80
test-compile-mandel-nofrac.js       : duk.O2 11.03 duk.O2.master 11.09 jerry  2.25
test-compile-mandel.js              : duk.O2 14.10 duk.O2.master 14.12 jerry  2.27
test-compile-short.js               : duk.O2  6.73 duk.O2.master  6.89 jerry  0.88
test-compile-string-ascii.js        : duk.O2  6.66 duk.O2.master  6.80 jerry   n/a
test-continue-fast.js               : duk.O2  1.68 duk.O2.master  1.70 jerry  2.20
test-continue-slow.js               : duk.O2  7.78 duk.O2.master  7.76 jerry  5.93
test-empty-loop-slowpath.js         : duk.O2  1.61 duk.O2.master  1.61 jerry  0.65
test-empty-loop.js                  : duk.O2  1.53 duk.O2.master  1.62 jerry  3.24
test-enum-basic.js                  : duk.O2  4.07 duk.O2.master  4.40 jerry  1.06
test-equals-fastint.js              : duk.O2  0.55 duk.O2.master  0.51 jerry  2.93
test-equals-nonfastint.js           : duk.O2  0.61 duk.O2.master  0.62 jerry  3.90
test-error-create.js                : duk.O2  2.15 duk.O2.master  2.22 jerry  0.76
test-fib.js                         : duk.O2  6.49 duk.O2.master  7.10 jerry  4.99
test-global-lookup.js               : duk.O2  6.31 duk.O2.master  9.50 jerry  2.19
test-hello-world.js                 : duk.O2  0.00 duk.O2.master  0.00 jerry  0.00
test-hex-decode.js                  : duk.O2  3.61 duk.O2.master  3.61 jerry   n/a
test-hex-encode.js                  : duk.O2   n/a duk.O2.master  2.84 jerry   n/a
test-jc-serialize-indented.js       : duk.O2  3.28 duk.O2.master  3.50 jerry   n/a
test-jc-serialize.js                : duk.O2  2.14 duk.O2.master  2.23 jerry   n/a
test-json-parse-hex.js              : duk.O2  3.18 duk.O2.master  3.23 jerry   n/a
test-json-parse-integer.js          : duk.O2  3.79 duk.O2.master  3.91 jerry   n/a
test-json-parse-number.js           : duk.O2  5.15 duk.O2.master  5.15 jerry   n/a
test-json-parse-string.js           : duk.O2  5.69 duk.O2.master  5.82 jerry   n/a
test-json-serialize-fastpath-loop.js: duk.O2  3.55 duk.O2.master  3.65 jerry 538.32
test-json-serialize-forceslow.js    : duk.O2  9.52 duk.O2.master  9.39 jerry  8.90
test-json-serialize-hex.js          : duk.O2  1.49 duk.O2.master  1.43 jerry   n/a
test-json-serialize-indented-deep100.js: duk.O2  1.78 duk.O2.master  1.86 jerry 137.05
test-json-serialize-indented-deep25.js: duk.O2  3.13 duk.O2.master  3.35 jerry 241.20
test-json-serialize-indented-deep500.js: duk.O2  1.18 duk.O2.master  1.23 jerry   n/a
test-json-serialize-indented.js     : duk.O2  5.77 duk.O2.master  6.04 jerry 106.67
test-json-serialize-jsonrpc-message.js: duk.O2  2.02 duk.O2.master  2.03 jerry   n/a
test-json-serialize-nofrac.js       : duk.O2  0.61 duk.O2.master  0.61 jerry  7.30
test-json-serialize-slowpath-loop.js: duk.O2  4.30 duk.O2.master  4.56 jerry  6.08
test-json-serialize.js              : duk.O2  6.07 duk.O2.master  5.89 jerry  8.85
test-json-string-bench.js           : duk.O2  3.41 duk.O2.master  3.89 jerry   n/a
test-json-string-stringify.js       : duk.O2  5.21 duk.O2.master  5.17 jerry   n/a
test-jx-serialize-bufobj-forceslow.js: duk.O2  4.25 duk.O2.master  4.66 jerry   n/a
test-jx-serialize-bufobj.js         : duk.O2  1.04 duk.O2.master  1.14 jerry   n/a
test-jx-serialize-indented.js       : duk.O2  3.34 duk.O2.master  3.42 jerry   n/a
test-jx-serialize.js                : duk.O2  2.14 duk.O2.master  2.22 jerry   n/a
test-mandel.js                      : duk.O2  2.82 duk.O2.master  2.75 jerry 13.28
test-object-garbage-2.js            : duk.O2  4.87 duk.O2.master  4.57 jerry  2.57
test-object-garbage.js              : duk.O2  4.72 duk.O2.master  4.39 jerry  2.76
test-object-literal.js              : duk.O2  2.76 duk.O2.master  2.49 jerry  2.29
test-prop-read-4.js                 : duk.O2  1.95 duk.O2.master  4.04 jerry  3.97
test-prop-read-8.js                 : duk.O2  1.95 duk.O2.master  4.35 jerry  3.91
test-prop-read-long-inherit.js      : duk.O2  0.35 duk.O2.master  6.83 jerry 14.37
test-prop-read-math-pi.js           : duk.O2  1.01 duk.O2.master  1.84 jerry  0.80
test-prop-read.js                   : duk.O2  1.98 duk.O2.master  4.13 jerry  3.96
test-prop-write-1024.js             : duk.O2  4.61 duk.O2.master  4.96 jerry  4.48
test-prop-write-16.js               : duk.O2  3.56 duk.O2.master  4.68 jerry  4.54
test-prop-write-256.js              : duk.O2  3.41 duk.O2.master  4.45 jerry  4.54
test-prop-write-32.js               : duk.O2  3.34 duk.O2.master  5.02 jerry  4.52
test-prop-write-4.js                : duk.O2  2.95 duk.O2.master  3.97 jerry  4.52
test-prop-write-48.js               : duk.O2  3.40 duk.O2.master  5.07 jerry  4.56
test-prop-write-64.js               : duk.O2  3.37 duk.O2.master  4.41 jerry  4.53
test-prop-write-8.js                : duk.O2  3.21 duk.O2.master  4.11 jerry  4.51
test-prop-write.js                  : duk.O2  3.00 duk.O2.master  4.01 jerry  4.52
test-random.js                      : duk.O2  2.31 duk.O2.master  2.38 jerry  1.85
test-reg-readwrite-object.js        : duk.O2  3.24 duk.O2.master  3.21 jerry 13.43
test-reg-readwrite-plain.js         : duk.O2  2.07 duk.O2.master  2.11 jerry 10.88
test-regexp-case-insensitive.js     : duk.O2 25.51 duk.O2.master 24.94 jerry  0.00
test-regexp-compile.js              : duk.O2  2.20 duk.O2.master  2.18 jerry  0.43
test-regexp-execute.js              : duk.O2  1.51 duk.O2.master  1.55 jerry  1.11
test-regexp-string-parse.js         : duk.O2  6.22 duk.O2.master  6.08 jerry   n/a
test-strict-equals-fastint.js       : duk.O2  0.54 duk.O2.master  0.54 jerry  3.03
test-strict-equals-nonfastint.js    : duk.O2  0.57 duk.O2.master  0.60 jerry  3.81
test-string-array-concat.js         : duk.O2  5.50 duk.O2.master  5.51 jerry   n/a
test-string-charlen-ascii.js        : duk.O2  1.08 duk.O2.master  1.14 jerry  0.74
test-string-charlen-nonascii.js     : duk.O2  2.69 duk.O2.master  2.64 jerry  0.54
test-string-compare.js              : duk.O2  1.98 duk.O2.master  1.92 jerry   n/a
test-string-decodeuri.js            : duk.O2  3.72 duk.O2.master  3.43 jerry   n/a
test-string-encodeuri.js            : duk.O2  4.03 duk.O2.master  4.09 jerry   n/a
test-string-garbage.js              : duk.O2  4.94 duk.O2.master  4.73 jerry  1.80
test-string-intern-grow-short.js    : duk.O2 11.68 duk.O2.master 12.08 jerry   n/a
test-string-intern-grow-short2.js   : duk.O2  4.59 duk.O2.master  4.91 jerry   n/a
test-string-intern-grow.js          : duk.O2 20.16 duk.O2.master 20.73 jerry   n/a
test-string-intern-grow2.js         : duk.O2  1.74 duk.O2.master  1.86 jerry   n/a
test-string-intern-match-short.js   : duk.O2  2.60 duk.O2.master  2.64 jerry   n/a
test-string-intern-match.js         : duk.O2  0.26 duk.O2.master  0.22 jerry   n/a
test-string-intern-miss-short.js    : duk.O2  3.07 duk.O2.master  3.07 jerry   n/a
test-string-intern-miss.js          : duk.O2  1.18 duk.O2.master  1.16 jerry   n/a
test-string-plain-concat.js         : duk.O2  0.86 duk.O2.master  0.86 jerry  0.49
test-string-uppercase.js            : duk.O2  2.18 duk.O2.master  2.23 jerry   n/a
test-textdecoder-ascii.js           : duk.O2  2.82 duk.O2.master  2.52 jerry   n/a
test-textdecoder-nonascii.js        : duk.O2  2.77 duk.O2.master  2.95 jerry   n/a
test-textencoder-ascii.js           : duk.O2  4.24 duk.O2.master  4.32 jerry   n/a
test-textencoder-nonascii.js        : duk.O2 10.84 duk.O2.master 10.81 jerry   n/a
test-try-catch-nothrow.js           : duk.O2  2.58 duk.O2.master  2.55 jerry  3.18
test-try-catch-throw.js             : duk.O2 39.53 duk.O2.master 38.41 jerry 15.03
test-try-finally-nothrow.js         : duk.O2  3.26 duk.O2.master  3.33 jerry  3.66
test-try-finally-throw.js           : duk.O2 50.35 duk.O2.master 48.72 jerry 17.94

@svaarala
Copy link
Owner Author

Octane score in master (with duk_hdecenv, duk_hobenv merged) averages 228, rebased against that this branch averages 240. So this simple form of property caching helps ~4% over master. Still, there are several approaches, one to be selected for 2.1.0.

@fatcerberus
Copy link
Contributor

What is "jerry" in the benchmarks?

@svaarala
Copy link
Owner Author

Jerryscript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants