mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
wide_integer_from_builtin and wide_integer_from_wide_integer sign-extend
through an `if (rhs < 0)` branch that selects between two separate fill
loops. In columnar conversion loops (ConvertImpl) this data-dependent
branch mispredicts on mixed-sign data and prevents vectorization even
when it predicts well.
Select the extension value (0 or -1) branchlessly instead and use a
single fill loop.
Standalone kernel benchmark of the columnar conversion loop (clang 21,
-march=x86-64-v3, 64k-element blocks, GB/s of processed data):
conversion before after
Int64 -> Int256, random sign 10.3 73.9
Int64 -> Int256, positive only 31.3 73.3
Int128 -> Int256, random sign 12.2 68.0
Int64 -> Int128 61.5 62.2
UInt64 -> UInt128/UInt256 unchanged
The same effect is visible at the query level: with the official
26.6.1 binary, `toInt256(toInt64(cityHash64(number)))` over 100M rows
takes 6.8x the time of the equivalent unsigned conversion in a single
thread, and 3.5x the time of the same conversion with positive-only
values.
Result equivalence with the previous implementation was verified over
36 million checks: all builtin integral types (int8/16/32/64, unsigned
variants) converted to UInt128/Int128/UInt256/Int256 including type
boundary values, 128-to-256-bit widening for all signedness
combinations, narrowing, and constexpr evaluation.
Co-Authored-By: Claude Fable 5 <[email protected]>
16 lines
985 B
XML
16 lines
985 B
XML
<test>
|
|
<!-- Conversion of native integers to 256-bit integers and widening of 128-bit to 256-bit integers.
|
|
Random 64-bit values give a random sign for the signed cases, which is hostile to a branchy
|
|
sign extension. The unsigned and 128-bit target queries guard the already fast paths. -->
|
|
|
|
<settings>
|
|
<max_threads>1</max_threads>
|
|
</settings>
|
|
|
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toInt256(toInt64(cityHash64(number))))</query>
|
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toInt256(toInt64(bitAnd(cityHash64(number), 4611686018427387903))))</query>
|
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toUInt256(cityHash64(number)))</query>
|
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toInt256(toInt128(toInt64(cityHash64(number)))))</query>
|
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toInt128(toInt64(cityHash64(number))))</query>
|
|
</test>
|