HappenLee opened a new pull request, #65738:
URL: https://github.com/apache/doris/pull/65738

   ### What problem does this PR solve?
   
   Issue Number: None
   
   Related PR: None
   
   Problem Summary:
   
   `BitPacking::UnpackValues` currently decodes every complete 32-value batch 
with scalar shifts and masks. This PR adds an x86 PDEP implementation for 
`uint8_t`, `uint16_t`, and `uint32_t`, with AVX2 widening for narrow `uint16_t` 
and `uint32_t` values.
   
   The optimized functions are compiled with `target("bmi2,avx2")`. Runtime 
dispatch uses `__builtin_cpu_supports("bmi2")` and 
`__builtin_cpu_supports("avx2")`; unsupported CPUs, architectures, output 
types, and remainder values continue to use the generic scalar implementation. 
Doris therefore does not require a global `-mbmi2` build flag.
   
   The PR also adds unit tests for every supported bit width, including full 
batches and truncated/remainder input, plus a reproducible benchmark comparing:
   
   - the generic scalar kernel;
   - the direct PDEP kernel;
   - the actual `BitPacking::UnpackValues` dispatch path.
   
   The benchmark covers 4K, 256K, and 1M values and validates optimized output 
against the scalar reference before measuring.
   
   #### Benchmark results
   
   Hardware: Intel Xeon Platinum 8457C, 2 MiB private L2 per core. Release 
build pinned to one CPU. Values below are CPU-time medians in microseconds.
   
   L2-sized working set: 256K `uint32_t` values. The output is 1 MiB and the 
packed input is 64-448 KiB.
   
   | bit width | scalar | PDEP | speedup |
   | ---: | ---: | ---: | ---: |
   | 2 | 41.0 | 27.9 | 1.47x |
   | 4 | 38.5 | 29.0 | 1.33x |
   | 6 | 61.6 | 28.6 | 2.15x |
   | 8 | 32.5 | 31.5 | 1.03x |
   | 10 | 77.6 | 36.0 | 2.16x |
   | 12 | 51.1 | 35.9 | 1.42x |
   | 14 | 50.6 | 47.1 | 1.07x |
   
   The same original cross-implementation benchmark with 1M `uint32_t` values 
produced the following medians:
   
   | bit width | Velox | Doris generic/scalar | Doris actual/PDEP |
   | ---: | ---: | ---: | ---: |
   | 2 | 766.6 | 184.2 | 279.0 |
   | 4 | 769.9 | 199.7 | 290.7 |
   | 6 | 768.8 | 260.1 | 277.1 |
   | 8 | 768.9 | 193.8 | 323.8 |
   | 10 | 770.8 | 372.9 | 267.2 |
   | 12 | 769.7 | 365.5 | 298.8 |
   | 14 | 769.1 | 351.0 | 322.4 |
   
   The result is workload- and bit-width-dependent. PDEP is faster for all 
measured widths while the working set remains in L2, although the gains at 
widths 8 and 14 are marginal. At 1M values, the actual PDEP path is faster than 
the scalar path at widths 10, 12, and 14, but slower at widths 2, 4, 6, and 8. 
Both Doris paths remain faster than the Velox baseline in this test. The 
multi-size benchmark is included so this trade-off remains visible and 
reproducible during review.
   
   ### Release note
   
   Improve bit-packed integer decoding on BMI2 and AVX2 capable x86 CPUs.
   
   ### Check List (For Author)
   
   - Test:
       - [x] Unit Test: `./run-be-ut.sh -j 48 --run --filter=BitPackingTest.*`
       - [x] Manual test: compiled and linked `benchmark_test`; ran scalar, 
direct PDEP, and actual-path cases at 256K and 1M values
       - [x] `build-support/check-format.sh`
       - [x] `build-support/run-clang-tidy.sh --build-dir be/build_RELEASE 
--files be/benchmark/benchmark_main.cpp be/test/util/bit_packing_test.cpp`
   - Behavior changed: Yes. Supported x86 CPUs use the PDEP path for complete 
32-value batches; all other cases retain the scalar path.
   - Does this need documentation: No
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to