From f858a8f287413b5184a911506f406fa0460d1b1d Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Wed, 9 Feb 2011 11:39:55 -0800 Subject: Precompute bit offset and bitmask for a small perf improvement. --- core/upb_def.c | 2 ++ core/upb_def.h | 4 +++- core/upb_msg.c | 2 +- core/upb_msg.h | 2 +- perf-regression-test.py | 3 ++- perf-tests.sh | 9 +++++---- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/core/upb_def.c b/core/upb_def.c index 8abb8bc..651afc1 100644 --- a/core/upb_def.c +++ b/core/upb_def.c @@ -727,6 +727,8 @@ static upb_flow_t upb_msgdef_endmsg(void *_b) { // want to use a different ordering that puts all the required bits // together. f->field_index = i; + f->set_bit_mask = 1 << (i % 8); + f->set_bit_offset = i / 8; size_t size, align; if (upb_isarray(f)) { diff --git a/core/upb_def.h b/core/upb_def.h index 34f31ec..28cc258 100644 --- a/core/upb_def.h +++ b/core/upb_def.h @@ -101,14 +101,16 @@ typedef struct _upb_fielddef { uint32_t byte_offset; // Where in a upb_msg to find the data. // These are set only when this fielddef is part of a msgdef. + upb_field_number_t number; upb_field_count_t field_index; // Indicates set bit. - upb_field_number_t number; upb_fieldtype_t type; upb_label_t label; // True if we own a ref on "def" (above). This is true unless this edge is // part of a cycle. bool owned; + uint8_t set_bit_mask; + uint16_t set_bit_offset; } upb_fielddef; // A variety of tests about the type of a field. diff --git a/core/upb_msg.c b/core/upb_msg.c index 05ee1e9..9dfbea4 100644 --- a/core/upb_msg.c +++ b/core/upb_msg.c @@ -142,7 +142,7 @@ void upb_msg_recycle(upb_msg **_msg, upb_msgdef *msgdef) { } INLINE void upb_msg_sethas(upb_msg *msg, upb_fielddef *f) { - msg->data[f->field_index/8] |= (1 << (f->field_index % 8)); + msg->data[f->set_bit_offset] |= f->set_bit_mask; } static upb_valueptr upb_msg_getappendptr(upb_msg *msg, upb_fielddef *f) { diff --git a/core/upb_msg.h b/core/upb_msg.h index 1318e08..8a3c63f 100644 --- a/core/upb_msg.h +++ b/core/upb_msg.h @@ -198,7 +198,7 @@ void upb_msg_recycle(upb_msg **msg, upb_msgdef *msgdef); // Tests whether the given field is explicitly set, or whether it will return a // default. INLINE bool upb_msg_has(upb_msg *msg, upb_fielddef *f) { - return (msg->data[f->field_index/8] & (1 << (f->field_index % 8))) != 0; + return (msg->data[f->set_bit_offset] & f->set_bit_mask) != 0; } INLINE upb_value upb_msg_get(upb_msg *msg, upb_fielddef *f) { diff --git a/perf-regression-test.py b/perf-regression-test.py index acd3ebc..ae3259c 100755 --- a/perf-regression-test.py +++ b/perf-regression-test.py @@ -10,7 +10,7 @@ set -v # Generate numbers for baseline. rm -rf perf-tmp git clone . perf-tmp -(cd perf-tmp && ./perf-tests.sh upb) +(cd perf-tmp && ../perf-tests.sh upb) cp perf-tmp/perf-tests.out perf-tests.baseline # Generate numbers for working directory. @@ -22,6 +22,7 @@ for line in baseline_file: test, speed = line.split(":") baseline[test] = int(speed) +print("\n\n=== PERFORMANCE REGRESSION TEST RESULTS:\n") wd_file = open("perf-tests.out") for line in wd_file: test, speed = line.split(":") diff --git a/perf-tests.sh b/perf-tests.sh index 1d8f4a8..3833572 100755 --- a/perf-tests.sh +++ b/perf-tests.sh @@ -3,6 +3,7 @@ # multiple times with a few different compiler flag combinations. # The output will be dumped to stdout and to perf-tests.out. +set -e MAKETARGET=benchmarks if [ x$1 == xupb ]; then MAKETARGET=upb_benchmarks @@ -11,23 +12,23 @@ fi rm -f perf-tests.out make clean -echo "-O3 -DNDEBUG -msse3" > perf-cppflags +echo "-O3 -DNDEBUG -msse3 -DUPB_THREAD_UNSAFE" > perf-cppflags make $MAKETARGET make benchmark | sed -e 's/^/plain./g' | tee -a perf-tests.out make clean -echo "-O3 -DNDEBUG -fomit-frame-pointer -msse3" > perf-cppflags +echo "-O3 -DNDEBUG -fomit-frame-pointer -msse3 -DUPB_THREAD_UNSAFE" > perf-cppflags make $MAKETARGET make benchmark | sed -e 's/^/omitfp./g' | tee -a perf-tests.out if [ x`uname -m` == xx86_64 ]; then make clean - echo "-O3 -DNDEBUG -msse3 -m32" > perf-cppflags + echo "-O3 -DNDEBUG -msse3 -m32 -DUPB_THREAD_UNSAFE" > perf-cppflags make upb_benchmarks make benchmark | sed -e 's/^/plain32./g' | tee -a perf-tests.out make clean - echo "-O3 -DNDEBUG -fomit-frame-pointer -msse3 -m32" > perf-cppflags + echo "-O3 -DNDEBUG -fomit-frame-pointer -msse3 -m32 -DUPB_THREAD_UNSAFE" > perf-cppflags make upb_benchmarks make benchmark | sed -e 's/^/omitfp32./g' | tee -a perf-tests.out fi -- cgit v1.2.3