From e64d77fb801fc3450b0828c2186273936c2946e2 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Sun, 28 Jul 2019 20:33:30 +0000 Subject: Avoid the compiler reloading the base register for every store. Removes 3 unnecessary loads in a very small leaf function. Instead of 2c: 48 8b 47 20 mov 0x20(%rdi),%rax 30: f2 0f 11 00 movsd %xmm0,(%rax) 34: 48 8b 47 20 mov 0x20(%rdi),%rax 38: 48 c7 40 08 00 00 00 movq $0x0,0x8(%rax) 3f: 00 40: 48 8b 47 20 mov 0x20(%rdi),%rax 44: 48 c7 40 10 00 00 00 movq $0x0,0x10(%rax) 4b: 00 4c: 48 8b 47 20 mov 0x20(%rdi),%rax 50: 48 89 48 18 mov %rcx,0x18(%rax) 54: c3 retq We get 23c: 48 8b 47 20 mov 0x20(%rdi),%rax 240: f2 0f 11 00 movsd %xmm0,(%rax) 244: 48 c7 40 08 00 00 00 movq $0x0,0x8(%rax) 24b: 00 24c: 48 c7 40 10 00 00 00 movq $0x0,0x10(%rax) 253: 00 254: 48 89 48 18 mov %rcx,0x18(%rax) 258: c3 retq --- .../vespa/searchlib/features/attributefeature.cpp | 44 ++++++++++++---------- .../src/vespa/searchlib/fef/featureexecutor.h | 3 ++ 2 files changed, 27 insertions(+), 20 deletions(-) (limited to 'searchlib') diff --git a/searchlib/src/vespa/searchlib/features/attributefeature.cpp b/searchlib/src/vespa/searchlib/features/attributefeature.cpp index 4f45b3090f0..45ecac90e9d 100644 --- a/searchlib/src/vespa/searchlib/features/attributefeature.cpp +++ b/searchlib/src/vespa/searchlib/features/attributefeature.cpp @@ -93,11 +93,11 @@ considerUndefined(ConstCharPtr value, BasicType::Type ) return search::features::util::getAsFeature(value); } - } namespace search::features { +namespace { /** * Implements the executor for fetching values from a single or array attribute vector @@ -201,12 +201,13 @@ SingleAttributeExecutor::execute(uint32_t docId) { typename T::LoadedValueType v = _attribute.getFast(docId); // value - outputs().set_number(0, __builtin_expect(attribute::isUndefined(v), false) - ? attribute::getUndefined() - : util::getAsFeature(v)); - outputs().set_number(1, 0.0f); // weight - outputs().set_number(2, 0.0f); // contains - outputs().set_number(3, 1.0f); // count + fef::NumberOrObject * o = outputs().get_raw(0); + o[0].as_number = __builtin_expect(attribute::isUndefined(v), false) + ? attribute::getUndefined() + : util::getAsFeature(v); + o[1].as_number = 0; // weight + o[2].as_number = 0; // contains + o[3].as_number = 1; // contains } template @@ -216,20 +217,21 @@ MultiAttributeExecutor::execute(uint32_t docId) const multivalue::Value * values = nullptr; uint32_t numValues = _attribute.getRawValues(docId, values); - outputs().set_number(0, __builtin_expect(_idx < numValues, true) - ? values[_idx].value() : 0.0f); - outputs().set_number(1, 0.0f); // weight - outputs().set_number(2, 0.0f); // contains - outputs().set_number(3, 0.0f); // count + fef::NumberOrObject * o = outputs().get_raw(0); + o[0].as_number = __builtin_expect(_idx < numValues, true) ? values[_idx].value() : 0; + o[1].as_number = 0; // weight + o[2].as_number = 0; // contains + o[3].as_number = 0; // count } void CountOnlyAttributeExecutor::execute(uint32_t docId) { - outputs().set_number(0, 0.0f); // value - outputs().set_number(1, 0.0f); // weight - outputs().set_number(2, 0.0f); // contains - outputs().set_number(3, _attribute.getValueCount(docId)); // count + fef::NumberOrObject * o = outputs().get_raw(0); + o[0].as_number = 0; // value + o[1].as_number = 0; // weight + o[2].as_number = 0; // contains + o[3].as_number = _attribute.getValueCount(docId); // count } template @@ -253,10 +255,11 @@ AttributeExecutor::execute(uint32_t docId) if (_idx < _buffer.size()) { value = considerUndefined(_buffer[_idx], _attrType); } - outputs().set_number(0, value); // value - outputs().set_number(1, 0.0f); // weight - outputs().set_number(2, 0.0f); // contains - outputs().set_number(3, _defaultCount); // count + fef::NumberOrObject * o = outputs().get_raw(0); + o[0].as_number = value; // value + o[1].as_number = 0; // weight + o[2].as_number = 0; // contains + o[3].as_number = _defaultCount; // count } @@ -298,6 +301,7 @@ WeightedSetAttributeExecutor::execute(uint32_t docId) outputs().set_number(3, count); // count } +} AttributeBlueprint::AttributeBlueprint() : fef::Blueprint("attribute"), diff --git a/searchlib/src/vespa/searchlib/fef/featureexecutor.h b/searchlib/src/vespa/searchlib/fef/featureexecutor.h index dc8a4ba6075..fd36fbe5a20 100644 --- a/searchlib/src/vespa/searchlib/fef/featureexecutor.h +++ b/searchlib/src/vespa/searchlib/fef/featureexecutor.h @@ -83,6 +83,9 @@ public: const NumberOrObject *get_raw(size_t idx) const { return &_outputs[idx]; } + NumberOrObject *get_raw(size_t idx) { + return &_outputs[idx]; + } size_t size() const { return _outputs.size(); } }; -- cgit v1.2.3