From 17040d4ee57dee078b7f38f393f49624e53b6eac Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Fri, 9 Jun 2023 15:17:00 +0200 Subject: [PATCH] JFConversionFixedPoint: More SIMD friendly --- jungfrau/JFConversionFixedPoint.cpp | 107 +++++++++------------------- jungfrau/JFConversionFixedPoint.h | 1 - 2 files changed, 35 insertions(+), 73 deletions(-) diff --git a/jungfrau/JFConversionFixedPoint.cpp b/jungfrau/JFConversionFixedPoint.cpp index a81c59c9..50b7067e 100644 --- a/jungfrau/JFConversionFixedPoint.cpp +++ b/jungfrau/JFConversionFixedPoint.cpp @@ -57,49 +57,6 @@ inline int32_t jf_round(int32_t in) { return in - half; } -void JFConversionFixedPoint::ConvertLine(int16_t *dest, const uint16_t *source, int line) { - auto gain_g0_aligned = std::assume_aligned<64>(gain_g0); - auto gain_g1_aligned = std::assume_aligned<64>(gain_g1); - auto gain_g2_aligned = std::assume_aligned<64>(gain_g2); - auto pedestal_g0_aligned = std::assume_aligned<64>(pedestal_g0); - auto pedestal_g1_aligned = std::assume_aligned<64>(pedestal_g1); - auto pedestal_g2_aligned = std::assume_aligned<64>(pedestal_g2); - - for (int i = 0; i < RAW_MODULE_COLS; i++) { - uint16_t gainbits = source[i] & 0xc000; - int32_t adc = source[i] & 0x3fff; - int32_t val = INT32_MIN; - - switch (gainbits) { - case 0: - [[likely]] - val = (adc - pedestal_g0_aligned[i + line * RAW_MODULE_COLS]) * gain_g0_aligned[i + line * RAW_MODULE_COLS]; - break; - case 0x4000: - if (source[i] != 0x4000) - val = (adc - pedestal_g1_aligned[i + line * RAW_MODULE_COLS]) * gain_g1_aligned[i + line * RAW_MODULE_COLS]; - break; - case 0xc000: - if (source[i] == 0xc000) - val = INT32_MAX; - else if (source[i] != 0xffff) - val = (adc - pedestal_g2_aligned[i + line * RAW_MODULE_COLS]) * gain_g2_aligned[i + line * RAW_MODULE_COLS]; - break; - default: - break; - } - - if (val <= INT16_MIN * (1L << FIXED_PRECISION)) - [[unlikely]] - dest[i] = INT16_MIN; - else if (val >= INT16_MAX * (1L << FIXED_PRECISION)) - [[unlikely]] - dest[i] = INT16_MAX; - else - dest[i] = static_cast(jf_round(val)/ (1L << FIXED_PRECISION)); - } -} - void JFConversionFixedPoint::ConvertModule(int16_t *dest, const uint16_t *source) { auto gain_g0_aligned = std::assume_aligned<64>(gain_g0); auto gain_g1_aligned = std::assume_aligned<64>(gain_g1); @@ -108,38 +65,44 @@ void JFConversionFixedPoint::ConvertModule(int16_t *dest, const uint16_t *source auto pedestal_g1_aligned = std::assume_aligned<64>(pedestal_g1); auto pedestal_g2_aligned = std::assume_aligned<64>(pedestal_g2); - for (int i = 0; i < RAW_MODULE_SIZE; i++) { - uint16_t gainbits = source[i] & 0xc000; - int32_t adc = source[i] & 0x3fff; - int32_t val = INT32_MIN; - switch (gainbits) { - case 0: - [[likely]] - val = (adc - pedestal_g0_aligned[i]) * gain_g0_aligned[i]; - break; - case 0x4000: - if (source[i] != 0x4000) - val = (adc - pedestal_g1_aligned[i]) * gain_g1_aligned[i]; - break; - case 0xc000: - if (source[i] == 0xc000) - val = INT32_MAX; - else if (source[i] != 0xffff) - val = (adc - pedestal_g2_aligned[i]) * gain_g2_aligned[i]; - break; - default: - break; + for (int line = 0; line < RAW_MODULE_LINES; line++) { + for (int col = 0; col < RAW_MODULE_COLS; col++) { + int i = col + line * RAW_MODULE_COLS; + int32_t adc = source[i] & 0x3fff; + int32_t val = (adc - pedestal_g0_aligned[i]) * gain_g0_aligned[i]; + dest[i] = static_cast(jf_round(val) / (1L << FIXED_PRECISION)); } - if (val <= INT16_MIN * (1L << FIXED_PRECISION)) - [[unlikely]] - dest[i] = INT16_MIN; - else if (val >= INT16_MAX * (1L << FIXED_PRECISION)) - [[unlikely]] - dest[i] = INT16_MAX; - else - dest[i] = static_cast(jf_round(val)/ (1L << FIXED_PRECISION)); + for (int col = 0; col < RAW_MODULE_COLS; col++) { + int i = col + line * RAW_MODULE_COLS; + uint16_t gainbits = source[i] & 0xc000; + int32_t adc = source[i] & 0x3fff; + + int32_t val = (adc - pedestal_g1_aligned[i]) * gain_g1_aligned[i]; + if (gainbits == 0x4000) + dest[i] = static_cast(jf_round(val) / (1L << FIXED_PRECISION)); + } + + for (int col = 0; col < RAW_MODULE_COLS; col++) { + int i = col + line * RAW_MODULE_COLS; + uint16_t gainbits = source[i] & 0xc000; + int32_t adc = source[i] & 0x3fff; + + int32_t val = (adc - pedestal_g2_aligned[i]) * gain_g2_aligned[i]; + + if (gainbits == 0xc000) + dest[i] = static_cast(jf_round(val) / (1L << FIXED_PRECISION)); + } + +#pragma ivdep + for (int col = 0; col < RAW_MODULE_COLS; col++) { + int i = col + line * RAW_MODULE_COLS; + if (source[i] == 0xc000) + dest[i] = INT16_MAX; + if (source[i] == 0xffff) + dest[i] = INT16_MIN; + } } } diff --git a/jungfrau/JFConversionFixedPoint.h b/jungfrau/JFConversionFixedPoint.h index b0cff7bf..779924d3 100644 --- a/jungfrau/JFConversionFixedPoint.h +++ b/jungfrau/JFConversionFixedPoint.h @@ -13,7 +13,6 @@ class JFConversionFixedPoint : public JFConversion { int32_t *gain_g0; int32_t *gain_g1; int32_t *gain_g2; - void ConvertLine(int16_t *dest, const uint16_t *source, int line); public: JFConversionFixedPoint(); ~JFConversionFixedPoint();