aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2019-07-28 20:33:30 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2019-07-29 12:20:56 +0000
commite64d77fb801fc3450b0828c2186273936c2946e2 (patch)
treeb0efac7911047f012009285a5b6e05685b68854c /searchlib
parent2a7c265eee4ad41e46a454c476043cae399912b4 (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.cpp44
-rw-r--r--searchlib/src/vespa/searchlib/fef/featureexecutor.h3
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(); }
};