perf(hex8): prepare guarded private four-column paired tangent packet
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
#include "hex8_pair_simd.h"
|
||||
|
||||
#include "hex8_pair_arithmetic.h"
|
||||
|
||||
#if defined(FESA_HEX8_PAIR_AVX2) && defined(_MSC_VER) && defined(_M_X64)
|
||||
#include <float.h>
|
||||
#include <intrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
namespace fesa::hex8_internal {
|
||||
void EvaluateMaterialPacketScalar(const MaterialPacketInput& input,
|
||||
PairPacket* output) {
|
||||
for (std::size_t lane = 0; lane < output->size(); ++lane) {
|
||||
const auto first = MultiplyPair(input.deviatoric_left[lane],
|
||||
input.deviatoric_right[lane]);
|
||||
const auto second = MultiplyPair(input.shear_left[lane],
|
||||
input.shear_right[lane]);
|
||||
const auto third = MultiplyPair(input.tensor_left[lane],
|
||||
input.gradient_dot[lane]);
|
||||
const auto material = AddPair(AddPair(first, second), third);
|
||||
(*output)[lane] = AddPair(input.accumulated[lane],
|
||||
MultiplyPair(material, input.weight));
|
||||
}
|
||||
}
|
||||
|
||||
MaterialPacketEvaluator SelectMaterialPacketEvaluator() {
|
||||
#if defined(FESA_HEX8_PAIR_AVX2) && defined(_MSC_VER) && defined(_M_X64)
|
||||
static const bool hardware_supported = [] {
|
||||
int info[4]{};
|
||||
__cpuid(info, 0);
|
||||
if (info[0] < 7) return false;
|
||||
__cpuidex(info, 1, 0);
|
||||
constexpr int required = (1 << 12) | (1 << 26) | (1 << 27) | (1 << 28);
|
||||
if ((info[2] & required) != required) return false;
|
||||
if ((_xgetbv(0) & 6U) != 6U) return false;
|
||||
__cpuidex(info, 7, 0);
|
||||
return (info[1] & (1 << 5)) != 0;
|
||||
}();
|
||||
if (!hardware_supported || !math_internal::ArithmeticEnvironmentSupported())
|
||||
return EvaluateMaterialPacketScalar;
|
||||
if ((_mm_getcsr() & 0x1f80U) != 0x1f80U)
|
||||
return EvaluateMaterialPacketScalar;
|
||||
unsigned int control = 0;
|
||||
if (_controlfp_s(&control, 0, 0) != 0 ||
|
||||
(control & _MCW_EM) != _MCW_EM)
|
||||
return EvaluateMaterialPacketScalar;
|
||||
return EvaluateMaterialPacketAvx2;
|
||||
#else
|
||||
return EvaluateMaterialPacketScalar;
|
||||
#endif
|
||||
}
|
||||
} // namespace fesa::hex8_internal
|
||||
Reference in New Issue
Block a user