diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2019-07-28 20:33:30 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2019-07-29 12:20:56 +0000 |
commit | e64d77fb801fc3450b0828c2186273936c2946e2 (patch) | |
tree | b0efac7911047f012009285a5b6e05685b68854c /searchlib | |
parent | 2a7c265eee4ad41e46a454c476043cae399912b4 (diff) |
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
Diffstat (limited to 'searchlib')
-rw-r--r-- | searchlib/src/vespa/searchlib/features/attributefeature.cpp | 44 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/fef/featureexecutor.h | 3 |
2 files changed, 27 insertions, 20 deletions
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>(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<T>::execute(uint32_t docId) { typename T::LoadedValueType v = _attribute.getFast(docId); // value - outputs().set_number(0, __builtin_expect(attribute::isUndefined(v), false) - ? attribute::getUndefined<feature_t>() - : 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<feature_t>() + : util::getAsFeature(v); + o[1].as_number = 0; // weight + o[2].as_number = 0; // contains + o[3].as_number = 1; // contains } template <typename T> @@ -216,20 +217,21 @@ MultiAttributeExecutor<T>::execute(uint32_t docId) const multivalue::Value<typename T::BaseType> * 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 <typename T> @@ -253,10 +255,11 @@ AttributeExecutor<T>::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<BT, T>::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(); } }; |