36[[nodiscard]]
static inline double hmax_pd_avx2(__m256d v)
noexcept {
37 __m256d hi = _mm256_permute2f128_pd(v, v, 0x01);
38 __m256d mx1 = _mm256_max_pd(v, hi);
39 __m256d swp = _mm256_permute_pd(mx1, 0x05);
40 __m256d mx2 = _mm256_max_pd(mx1, swp);
41 return _mm256_cvtsd_f64(mx2);
52 constexpr std::size_t LANE = 4;
54 const __m256d abs_mask = _mm256_castsi256_pd(
55 _mm256_set1_epi64x(
static_cast<long long>(
ABS_MASK_U64)));
58 __m256d vmax = _mm256_setzero_pd();
60 for (; i + LANE <= n; i += LANE) {
61 __m256d v = _mm256_loadu_pd(velocities + i);
62 __m256d abs_v = _mm256_and_pd(v, abs_mask);
63 vmax = _mm256_max_pd(vmax, abs_v);
68 const double a = std::abs(velocities[i]);
69 if (a > batch_max) batch_max = a;
73 if (batch_max > running_max) running_max = batch_max;
74 const double denom = (running_max > 0.0) ? running_max : 1.0;
77 const __m256d denom_v = _mm256_set1_pd(denom);
81 for (; i + LANE <= n; i += LANE) {
82 __m256d v = _mm256_loadu_pd(velocities + i);
83 __m256d abs_v = _mm256_and_pd(v, abs_mask);
84 __m256d beta = _mm256_div_pd(abs_v, denom_v);
85 beta = _mm256_min_pd(beta, clamp_v);
86 _mm256_storeu_pd(out + i, beta);
90 const double abs_v = std::abs(velocities[i]);
91 double beta = abs_v / denom;