Punisheroot commented on PR #50710:
URL: https://github.com/apache/arrow/pull/50710#issuecomment-5123630193

   Thanks for the Conbench report. I investigated all 15 possible regressions
   reported for PR commit 74acebbf0344efcdc9f74593040d43fc2dbb3603 .
   
   The follow-up fix described below is included in commit 
59e8845c3f038588835ddefec4900e66a5ee71ec.
   
   ## Root cause
   
   Six regressions affected `BM_ArrowBinaryPlain` on the
   `amd64-c6a-4xlarge-linux` runner:
   
   - `DecodeArrow_Dense`: 4,096, 32,768, and 65,536 values
   - `DecodeArrowNonNull_Dense`: 4,096, 32,768, and 65,536 values
   
   These regressions were real but indirect. The Plain decoding algorithm was 
not
   changed. Instead, the additional dictionary decoding code changed GCC 14's
   inlining decision for `decoder.cc`. GCC stopped inlining the existing
   `ArrowBinaryHelper::AppendValue` implementation into the Plain decode loop,
   introducing an out-of-line call for every decoded value.
   
   I confirmed this by comparing the generated GCC 14 code for the baseline, the
   original PR, and the follow-up fix.
   
   ## Classification of the other results
   
   Seven alerts belong to separate Arrow benchmark executables: the two temporal
   cases, the ARM allocator case, and the four bit/cast/unpacking cases on the 
m5
   runner. These executables do not link `libparquet`, and none of the three 
files
   changed by this PR contributes code to them. Their measured deltas are 
genuine
   observations from those runs, but there is no source or binary dependency 
through
   which this PR could change their benchmark code.
   
   The Boolean RLE and FLBA cases require a more cautious classification because
   they are part of `parquet-encoding-benchmark` and therefore share the 
executable
   or `libparquet` affected by the PR. Neither executes the modified dictionary
   path:
   
   - the GCC 14 hot function body for Boolean RLE is byte-identical between the
     baseline, original PR, and follow-up;
   - FLBA calls `arrow::util::internal::ByteStreamSplitDecode` directly rather 
than
     the modified Parquet decoder.
   
   Paired GCC 14 controls did not reproduce either regression. With the complete
   baseline/PR/follow-up executables and libraries, the median changes versus 
the
   baseline were:
   
   - Boolean RLE: original PR `-0.59%`, follow-up `-0.80%`;
   - FLBA: original PR `+0.49%`, follow-up `-0.05%`.
   
   A second experiment using the same executable for every comparison and 
changing
   only `libparquet` also remained within approximately 0.5%. These local 
results
   strongly suggest that the Conbench RLE and FLBA alerts were run- or
   machine-specific. However, because code layout differs in the linked c6a 
binary,
   a new Apache-runner result remains the authoritative confirmation.
   
   ## Follow-up fix
   
   The follow-up adds a narrowly scoped overload for the known-size `BinaryType`
   append path:
   
   - the common per-value path is explicitly kept inline;
   - the rare chunk-rollover path is moved to a no-inline helper;
   - the existing optional-size path remains unchanged for other callers;
   - the dictionary predecode, validation, exact reservation, and reusable 
scratch
     buffer remain unchanged.
   
   This restores the intended generated code without increasing GCC's global
   inline budget. The final GCC 14 `decoder.cc` object contains 277 fewer bytes 
of
   text than the original PR object.
   
   ## Performance validation
   
   I could not reproduce the exact Apache c6a host locally, so these 
measurements
   do not replace a new Conbench run. I used GCC 14.2, `-O2`, the c6a 
optimization
   flags, CPU pinning, rotated execution order, and paired comparisons.
   
   For the six originally regressed Plain cases:
   
   - follow-up versus baseline: 25.3% to 51.6% faster;
   - follow-up versus the original PR: 38.8% to 66.6% faster.
   
   The dictionary optimization remains intact:
   
   - follow-up versus baseline: 29.0% to 63.9% faster;
   - follow-up versus the original PR: median differences from `-0.56%` to
     `+0.92%`, with no systematic loss.
   
   All 76 registered `BM_ArrowBinary*` cases were screened in six paired rounds.
   No repeatable regression remained. The only short-run outlier was `+2.70%`;
   twelve longer pairs for that exact case produced a `-0.05%` median with six
   positive and six negative results.
   
   ## Correctness validation
   
   The exact final source passed:
   
   - `parquet-encoding-test`: 136/136;
   - `parquet-reader-test`: 149 passed, 5 skipped;
   - `parquet-arrow-reader-writer-test`: 823 passed, 9 skipped;
   - total: 1,108 passed, 14 skipped, 0 failed;
   - 16 focused ASan/UBSan Plain and Dictionary cases, with no findings.
   
   A disposable diagnostic build also forced the normally rare chunk rollover at
   4 KiB and verified every emitted chunk against the expected array slices for
   Plain and Dictionary decoding, with and without nulls.
   
   ## Relation to the original PR benchmarks
   
   The original Windows/MSVC measurements remain valid for the dictionary cases
   they measured: they showed a 17.2%–25.5% improvement at 65,536 values. 
However,
   they did not exercise the Linux/GCC Plain-path code-generation side effect 
later
   exposed by Conbench.
   
   The follow-up therefore supplements the original measurements with the 
missing
   Linux/GCC controls. It preserves the dictionary improvement while removing 
the
   indirect Plain regression.
   
   A new Conbench run on the Apache runners is still required for final 
validation.
   
   Thank you!


-- 
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]

Reply via email to