Repository navigation
POCL: default to more than four work-groups per thread - #956
Conversation
|
Documentation preview: https://juliagpu.github.io/KernelAbstractions.jl/previews/PR956/ |
Benchmark resultsCompared with 8a985320e, the latest measured ancestor of the merge base (14 commits before it). Times are the minimum time of every benchmark. A change is unusual when it exceeds both three times the benchmark's typical change between consecutive runs on the default branch and a minimum per category (performance 3%, latency 5%, applications 3%, other 3%). A benchmark that starts or stops allocating is listed however few the allocations. A single run can still be a fluke, so rerun before drawing conclusions.
All benchmarks
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## tb/pocl-launch-cost-906 #956 +/- ##
===========================================================
- Coverage 84.81% 84.81% -0.01%
===========================================================
Files 31 31
Lines 2924 2923 -1
===========================================================
- Hits 2480 2479 -1
Misses 444 444 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
b9d2da9 to
39bbdf1
Compare
8ce801f to
5f79343
Compare
A CPU launch without a work-group size followed PoCL's choice, which
stops splitting once there are more than half as many work-groups as
threads. With block k running on thread k, a few large work-groups that
don't divide evenly among the threads leave some idle: a 132x132 launch
on 8 threads became 6 work-groups of up to 4096 work-items. This is
common for 2-D launches whose work-items loop over a column, as the
vertical integrals in ocean models do.
Keep halving the work-group while there are at most four work-groups per
thread, still not below 4 times the preferred work-group size multiple.
Launches that already have enough work-groups are unchanged.
The bounds-check test launched 4097 work-items to force partial
work-groups, but 4 threads now fit them into 17 work-groups of 241. Use
a prime ndrange, which no work-group size divides.
A 2-D launch whose work-items each sum and update a column (pinned to one
CCD of a Threadripper PRO 7995WX, `-t N,0`):
8 threads 16 threads
132x132x32 81-82 -> 67 µs (-18%) 48-49 -> 38 µs (-22%)
100x100x50 98 -> 72 µs (-27%) 51-52 -> 40 µs (-22%)
256x256x16 1.06 -> 1.05-1.06 ms 0.54 -> 0.51-0.55 ms
With 1 thread, all three are unchanged. In Oceananigans, which used its
own row-spanning CPU work-group to avoid this, the new default keeps time
steps (32³ to 128²x32, 1 to 16 threads) within ±2% of that choice, and
up to 11% faster for small grids at 8 to 16 threads; PoCL's choice was
up to 23% slower.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WMgptfbgngptRnuETEaRNs
5f79343 to
d9b042c
Compare
Stacked on #941 (and #906).
A
CPUlaunch without a workgroup size currently follows PoCL'spocl_default_local_size_optimizer, which stops splitting once there are more than half as many work-groups as threads. With #906's scheduling (blockkon threadk), that leaves threads idle whenever the few large work-groups don't divide evenly among them. For example, a 132×132 launch on 8 threads ends up as 6 work-groups of up to 4096 work-items: two threads have nothing to do, and a thread that finishes early can't pick up more. 2-D launches whose work-items loop over a column, like the vertical integrals in ocean models, hit this often.This PR keeps halving the work-group while there are at most four work-groups per thread. The floor stays at 4× the preferred work-group size multiple, so work-groups stay large enough to vectorize. Launches that already have enough work-groups are unchanged. 1-thread launches get smaller work-groups but run the same work serially.
Performance
A 2-D launch whose work-items sum and update a column, on a Threadripper PRO 7995WX pinned to one CCD (
julia -t N,0):With 1 thread, all three are unchanged.
Oceananigans uses its own row-spanning CPU work-group to avoid this problem. With this PR, letting KernelAbstractions choose gives hydrostatic and nonhydrostatic time steps (32³ to 128²×32, 1 to 16 threads) within ±2% of that custom choice, and up to 11% faster for small grids at 8–16 threads. With #941's rule they were up to 23% slower.
Without #906's scheduling (KernelAbstractions 0.10.5), more work-groups per thread made launches slower at 16 threads, so this change belongs on top of #906.
Reproducer
Tests
The "POCL workgroup size" testset now checks the new rule instead of PoCL's choices, with a regression case for the 132×132 launch. The "POCL bounds checks" testset launched 4097 work-items to force partial work-groups, but on 4 threads the new rule fits them into 17 work-groups of 241. It now uses a prime ndrange, which no work-group size divides.