perf: reuse owned shell Jet Hessians in accumulation
This commit is contained in:
@@ -386,6 +386,9 @@ class Hessian {
|
||||
/// @brief Identifies only the immutable zero Hessian, independently of seeds.
|
||||
bool IsImplicitZero() const { return !values_; }
|
||||
|
||||
/// @brief Allows a consumed temporary to reuse only its own materialized data.
|
||||
bool HasUniqueStorage() const { return values_ && values_.use_count() == 1; }
|
||||
|
||||
/// @brief Gets fresh output storage without redundant zero initialization.
|
||||
/// @note Only fresh operator results use this pointer; all 576 entries must
|
||||
/// be written before any read or copy of the result.
|
||||
@@ -488,6 +491,30 @@ Jet operator+(const Jet& left, const Jet& right) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief Adds to a consumed temporary without allocating another Hessian.
|
||||
/// @note Shared/live aliases and unmasked exceptions retain the original path.
|
||||
Jet operator+(Jet&& left, const Jet& right) {
|
||||
if ((_mm_getcsr() & _MM_MASK_MASK) != _MM_MASK_MASK || &left == &right ||
|
||||
!left.second.HasUniqueStorage())
|
||||
return static_cast<const Jet&>(left) + right;
|
||||
left.value = left.value + right.value;
|
||||
left.directional_first = left.directional_first + right.directional_first;
|
||||
left.directional_second = left.directional_second + right.directional_second;
|
||||
for (std::size_t index = 0U; index < kGlobalDofCount; ++index) {
|
||||
left.first[index] = left.first[index] + right.first[index];
|
||||
left.mixed_first[index] = left.mixed_first[index] + right.mixed_first[index];
|
||||
left.mixed_second[index] = left.mixed_second[index] + right.mixed_second[index];
|
||||
}
|
||||
left.constant_derivatives = left.constant_derivatives &&
|
||||
right.constant_derivatives &&
|
||||
std::isfinite(left.value);
|
||||
const double* right_second = right.second.ReadData();
|
||||
double* left_second = left.second.Data();
|
||||
for (std::size_t index = 0U; index < kHessianSize; ++index)
|
||||
left_second[index] = left_second[index] + right_second[index];
|
||||
return std::move(left);
|
||||
}
|
||||
|
||||
/// @brief Subtracts two second-order trial-coordinate quantities.
|
||||
Jet operator-(const Jet& left, const Jet& right) {
|
||||
Jet result{};
|
||||
@@ -1105,7 +1132,7 @@ Jet FrameComponent(const JetVector3& left, const JetTensor& tensor,
|
||||
Jet result{};
|
||||
for (std::size_t row = 0U; row < 3U; ++row) {
|
||||
for (std::size_t column = 0U; column < 3U; ++column) {
|
||||
result = result + left[row] * tensor[row][column] * right[column];
|
||||
result = std::move(result) + left[row] * tensor[row][column] * right[column];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -1183,9 +1210,9 @@ Jet PhysicalEnergy(const std::array<Vector3, kNodeCount>& coordinates,
|
||||
shear * strain[4U]};
|
||||
Jet density{};
|
||||
for (std::size_t component = 0U; component < strain.size(); ++component) {
|
||||
density = density + strain[component] * stress[component];
|
||||
density = std::move(density) + strain[component] * stress[component];
|
||||
}
|
||||
energy = energy + 0.5 * reference.reference_jacobian * density;
|
||||
energy = std::move(energy) + 0.5 * reference.reference_jacobian * density;
|
||||
}
|
||||
}
|
||||
if (!IsFinite(energy)) {
|
||||
|
||||
Reference in New Issue
Block a user