mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2026-10-28 16:18:23 +08:00
`NumericArrayIndex<IndexOfAction, T>::findInBlocks` returned the rescan of the matching block from inside the block loop. That kept clang from vectorizing the `found |=` reduction for 4- and 8-byte elements on ARM, so `indexOf` ran a scalar prefix, a scalar block reduction and a scalar rescan, which is slower than the scalar loop it replaced. `has` was not affected. Now the loop only breaks, and the block or the tail is rescanned after it. `NumericArrayIndex<IndexOfAction, T>::vector` for `Int32`, `UInt32`, `Int64`, `UInt64`, `Float32` and `Float64` now has the same NEON compares as `has`. The `has` code is unchanged on both x86 and ARM. On x86 the `indexOf` block loop stays the same, and the unrolled rescan becomes a short loop. `clickhouse local` on Neoverse-V2, `max_threads = 1`, best of 9, 4M rows: - `Array(UInt32)` of 24, hit in 8..15: 72 -> 52 ms - `Array(UInt32)` of 24, hit at 9: 48 -> 26 ms - `Array(Int64)` of 16, hit in 8..15: 58 -> 53 ms Add a short-array case to the `array_index_simd_numeric` performance test. Closes: https://github.com/ClickHouse/ClickHouse/issues/123338 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
45 lines
1.6 KiB
XML
45 lines
1.6 KiB
XML
<test>
|
|
<settings>
|
|
<max_threads>1</max_threads>
|
|
<max_block_size>8192</max_block_size>
|
|
</settings>
|
|
|
|
<create_query>DROP TABLE IF EXISTS perf_array_index_simd_numeric</create_query>
|
|
<create_query>
|
|
CREATE TABLE perf_array_index_simd_numeric (arr Array(UInt32)) ENGINE = Memory
|
|
</create_query>
|
|
<fill_query>
|
|
INSERT INTO perf_array_index_simd_numeric
|
|
SELECT materialize(range(4096)::Array(UInt32))
|
|
FROM numbers(20000)
|
|
</fill_query>
|
|
<!-- Short arrays with the first match just past the scalar prefix, in the first block. -->
|
|
<create_query>DROP TABLE IF EXISTS perf_array_index_simd_numeric_short</create_query>
|
|
<create_query>
|
|
CREATE TABLE perf_array_index_simd_numeric_short (arr Array(UInt32)) ENGINE = Memory
|
|
</create_query>
|
|
<fill_query>
|
|
INSERT INTO perf_array_index_simd_numeric_short
|
|
SELECT arrayMap(x -> if(x = 8 + cityHash64(number) % 8, 0, x + 1), range(24))::Array(UInt32)
|
|
FROM numbers(4000000)
|
|
</fill_query>
|
|
<!-- Keep one representative input, but time each function independently. -->
|
|
<query>
|
|
SELECT sum(has(arr, 4294967295))
|
|
FROM perf_array_index_simd_numeric
|
|
FORMAT Null
|
|
</query>
|
|
<query>
|
|
SELECT sum(indexOf(arr, 100))
|
|
FROM perf_array_index_simd_numeric
|
|
FORMAT Null
|
|
</query>
|
|
<query>
|
|
SELECT sum(indexOf(arr, 0))
|
|
FROM perf_array_index_simd_numeric_short
|
|
FORMAT Null
|
|
</query>
|
|
<drop_query>DROP TABLE IF EXISTS perf_array_index_simd_numeric</drop_query>
|
|
<drop_query>DROP TABLE IF EXISTS perf_array_index_simd_numeric_short</drop_query>
|
|
</test>
|