perf(hex8): packetize ordered gradient and geometric contractions
This commit is contained in:
@@ -246,11 +246,38 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
|
||||
gradient_stress[a][j][l] = gradients[a][j] * s[l][j];
|
||||
for (std::size_t a = 0; a < 8; ++a) {
|
||||
std::array<HighLow, 8> dots{};
|
||||
std::array<HighLow, 8> weighted_geo{};
|
||||
if (use_packets)
|
||||
for (std::size_t first_b = 0; first_b < 8; first_b += 4) {
|
||||
hex8_internal::GeometryPacketInput input{};
|
||||
const auto raw_pair = [](HighLow pair) {
|
||||
return hex8_internal::PacketPair{pair.high, pair.low};
|
||||
};
|
||||
input.weight = raw_pair(HighLow{point.weight});
|
||||
for (std::size_t j = 0; j < 3; ++j) {
|
||||
input.gradient_a[j] = raw_pair(gradients[a][j]);
|
||||
for (std::size_t l = 0; l < 3; ++l)
|
||||
input.gradient_stress[j][l] = raw_pair(gradient_stress[a][j][l]);
|
||||
for (std::size_t lane = 0; lane < 4; ++lane)
|
||||
input.gradient_b[j].values[lane] =
|
||||
raw_pair(gradients[first_b + lane][j]);
|
||||
}
|
||||
hex8_internal::GeometryPacketOutput output;
|
||||
// Same selector contract as material; unsupported/linear stays below.
|
||||
hex8_internal::EvaluateGeometryPacketAvx2(input, &output);
|
||||
for (std::size_t lane = 0; lane < 4; ++lane) {
|
||||
dots[first_b + lane] = {output.gradient_dot.values[lane].high,
|
||||
output.gradient_dot.values[lane].low};
|
||||
weighted_geo[first_b + lane] =
|
||||
{output.weighted_geometric.values[lane].high,
|
||||
output.weighted_geometric.values[lane].low};
|
||||
}
|
||||
}
|
||||
for (std::size_t b = 0; b < 8; ++b) {
|
||||
const auto dot = Dot(gradients[a], gradients[b]);
|
||||
const auto dot = use_packets ? dots[b] : Dot(gradients[a], gradients[b]);
|
||||
dots[b] = dot;
|
||||
HighLow geo;
|
||||
if (nonlinear)
|
||||
if (nonlinear && !use_packets)
|
||||
for (std::size_t j = 0; j < 3; ++j)
|
||||
for (std::size_t l = 0; l < 3; ++l)
|
||||
geo += gradient_stress[a][j][l] * gradients[b][l];
|
||||
@@ -265,7 +292,8 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
|
||||
material[row][column] += mat * HighLow{point.weight};
|
||||
}
|
||||
if (i == k)
|
||||
geometric[row][column] += geo * HighLow{point.weight};
|
||||
geometric[row][column] +=
|
||||
use_packets ? weighted_geo[b] : geo * HighLow{point.weight};
|
||||
}
|
||||
}
|
||||
if (use_packets)
|
||||
|
||||
Reference in New Issue
Block a user