Repository navigation
Call sincos instead of separate sin and cos of one angle - #127214
Conversation
`h3_functions` #4 (`h3CellAreaM2`) was 20% slower on aarch64: in the glibc build LLVM merges `sin(x)` and `cos(x)` into one `sincos` call, which shares the argument reduction, but it assumes `sincos` only in glibc, Fuchsia and Android, so the musl build made both calls. An explicit `sincos` call does not help on its own: Clang turns it into the `llvm.sincos` intrinsic, and for a musl target LLVM lowers that to `sin` and `cos` again. - Compile with `-fno-builtin-sincos` under musl, so that `sincos` stays a call. - Link llvm-libc's correctly rounded `sincos`, which gives the same bits as its `sin` and `cos`. - Bump `contrib/h3` to call `sincos` in `cagnoli` (the cell area functions). - Add `sinCos` and use it in `geoToUTM`, `UTMToGeo` and `colorOKLCHToSRGB`. The results of these functions over 200000 inputs are identical before and after. https://s3.amazonaws.com/clickhouse-test-reports/praktika.html?PR=109239&sha=a685010407d544ee0b02294d34118bd48f46ff84&name_0=PR&name_1=Performance%20Comparison%20%28arm_release%2C%20master_head%2C%201%2F6%29 #109239 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 1ffa828)
…ables` The output parameters of `sinCos` left the callers' variables uninitialized, which `clang-tidy` rejects. https://s3.amazonaws.com/clickhouse-test-reports/praktika.html?PR=109239&sha=1ffa828af25b70add84fe7bb2f88fe5765159e60&name_0=PR&name_1=Build%20%28arm_tidy%2C%202%2F4%29 #109239 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 16f3316)
…cond one The fork's `_sincos` used `__builtin_sincos`, which LLVM splits back into `sin` and `cos` for musl targets, so it is now declared with the `sincos` assembler label and `cagnoli` uses it as well. Branch `sincos-on-musl` of ClickHouse/h3, on top of `ClickHouse/v4.5.0`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Workflow [PR], commit [0d02585] Summary: ✅
AI ReviewSummaryThe PR preserves explicit paired sine/cosine calls under musl, exports LLVM-libc's Findings
💡 Nits
PR Metadata
Tests
Final Verdict |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| "${LIBLLVMLIBC_SOURCE_DIR}/src/math/generic/scalbn.cpp" | ||
| "${LIBLLVMLIBC_SOURCE_DIR}/src/math/generic/scalbnl.cpp" | ||
| "${LIBLLVMLIBC_SOURCE_DIR}/src/math/generic/sin.cpp" | ||
| "${LIBLLVMLIBC_SOURCE_DIR}/src/math/generic/sincos.cpp" |
There was a problem hiding this comment.
💡 Narrow the changelog's unconditional “with identical results” claim. Adding this source exports LLVM-libc's sincos in glibc builds too, replacing the glibc implementation previously used by optimizer-generated paired calls. In a standalone aarch64 probe using the pinned sources and repository math defines, 567 of 200,000 sampled pairs differed from glibc. For example, at x = 0x1.fb9664c826b3dp+1, glibc returns cosine -0x1.5bd25a6ee0c56p-1, whereas LLVM-libc returns -0x1.5bd25a6ee0c57p-1.
The comparison against LLVM-libc's separate sin and cos did match. Please limit the identity statement to that comparison, or remove it and mention that glibc builds can have final-bit rounding changes. This is a documentation nit, not a correctness blocker.
ClickHouse/h3#14 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… into sincos-single-call
| "${LIBLLVMLIBC_SOURCE_DIR}/src/math/generic/scalbn.cpp" | ||
| "${LIBLLVMLIBC_SOURCE_DIR}/src/math/generic/scalbnl.cpp" | ||
| "${LIBLLVMLIBC_SOURCE_DIR}/src/math/generic/sin.cpp" | ||
| "${LIBLLVMLIBC_SOURCE_DIR}/src/math/generic/sincos.cpp" |
There was a problem hiding this comment.
sincos globally.
This source is linked for glibc builds as well as musl, and the normal release link uses --whole-archive, so it replaces the glibc sincos already used by compiler-generated paired calls throughout the executable. Sharing argument reduction does not establish a speedup over that existing paired implementation.
The completed performance run measures h3_functions query 4 at 143.8 → 153.1 ms on ARM (+6.4%) and 140.9 → 148.5 ms on AMD64 (+5.3%). Both changes are below CI's 15% reporting floor, and one run does not prove a regression, but neither demonstrates this PR's performance benefit. That run uses the same LLVM revision and H3 source contents as the current head.
Please provide a focused before/after comparison for the intended musl build and the glibc build. If replacing glibc's implementation is slower, scope the LLVM-libc export to musl or otherwise preserve the faster implementation. The linked report from PR #109239 identifies the original problem; it does not measure this patch's benefit.
Build profile diff (arm_release)Comparing ✅ No significant changes. Binary sizes
The official master build is compiled with Object file sizes15 object files changed (+34.22 KiB total), 1 added.
719 more object files are built by the master warmup baseline only (it builds every object-file target, a pull request build only Compile time of recompiled translation units25 translation units recompiled, 15 s compile time in total, 8 of them have a recent master baseline. |
Take master's versions of `CompressionCodecT64.cpp` and `contrib/h3`: both are the reviewed final forms of the changes this branch carried (#127214 and the portable `T64` matrix fill). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Related: #109239
h3_functions#4 (h3CellAreaM2) was 20% slower on aarch64 in the musl build: in the glibc build LLVM mergessin(x)andcos(x)into onesincoscall, which shares the argument reduction, but it assumessincosonly in glibc, Fuchsia and Android, so the musl build made both calls. An explicitsincoscall does not help on its own: Clang turns it into thellvm.sincosintrinsic, and for a musl target LLVM lowers that tosinandcosagain.-fno-builtin-sincosunder musl, so thatsincosstays a call.sincos, which gives the same bits as itssinandcos.contrib/h3so that its_sincoshelper really callssincos(its__builtin_sincosis split back intosinandcosfor musl targets) and use it incagnoli, the cell area functions: merged intoClickHouse/v4.5.0in Make_sincosreach libm'ssincoson every Linux libc, and use it incagnolih3#14.sinCosand use it ingeoToUTM,UTMToGeoandcolorOKLCHToSRGB.The results of these functions over 200000 inputs are identical before and after.
Perf report where it was found: https://s3.amazonaws.com/clickhouse-test-reports/praktika.html?PR=109239&sha=a685010407d544ee0b02294d34118bd48f46ff84&name_0=PR&name_1=Performance%20Comparison%20%28arm_release%2C%20master_head%2C%201%2F6%29
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
h3CellAreaM2,h3CellAreaRads2,geoToUTM,UTMToGeoandcolorOKLCHToSRGBcompute the sine and cosine of one angle with a singlesincoscall in every build, with identical results.🤖 Generated with Claude Code
Workflow [PR]
Sync PR [sync-upstream/pr/127214]
Version info
26.11.1.590-master(included in26.11and later)