Repository navigation
Commit be9c495
perf(kernel): persistent worker pool instead of threads per batch (6% faster) (#4546)
* docs: design for a persistent scratch and thread pool in the kernel
Batching made planning 35% faster but threading on top of it bought 1.6%. A census showed why: 25,091
batch calls with a median of 6 jobs, against which a fresh thread pool and a fresh 70KB scratch are
built per call. Staged so the low-risk half (per-thread scratch, which also helps the serial default)
is measured before the concurrency half.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* perf(kernel): give each thread one scratch instead of one per call
PARKED - measured as a no-op, do not merge on its own.
Replaces the three per-call PkScratch constructions with a thread_local accessor, so a thread grows
its ~70KB of buffers once rather than once per pk_run_batch call (~25,000 of them per plan).
Measured on the serial benchmark, interleaved, best of 3: 26.291s before, 26.344s after - no
difference against ~1.8% run-to-run spread. The hypothesis was wrong: the kernel's comment about the
allocator being the bottleneck was recorded under four threads contending, and one thread repeatedly
allocating and freeing the same-sized block never leaves the allocator's thread cache.
Kept on this branch because the persistent-worker design needs per-worker scratch anyway, and the two
tests are worth having either way: one pins that the buffers stop being rebuilt per call (it fails
before this change), the other that a reused scratch cannot leak between contexts of different
n_steps (verified by mutation - relaxing the assign to skip shrinking makes it fail).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* perf(kernel): keep a persistent worker pool instead of threads per batch
pk_run_batch built and joined a fresh std::vector<std::thread> on every call. Measured over one
benchmark plan that was 201,545 thread creations costing 1.5s against 3.1s of simulation, which is
why threading was worth only 1.6% - the creation was cancelling what the parallelism won.
Workers now park on a condition variable for the life of the process, and each has its own flag and
condvar so a batch wakes exactly the lanes it needs. Broadcasting instead cost most of the win: a
six-job batch woke all fifteen workers, ~250,000 wasted wakeups per plan, and measured 1.3% against
3.7% for targeted wakes. The calling thread takes lane 0 itself, so a six-job batch wakes five.
Also gives each thread one scratch instead of one per call. That is a no-op on its own (26.291s vs
26.344s, inside noise - the allocator never left its thread cache) but the parked workers need it.
20-scenario benchmark, best of 3: 26.33s serial, 24.71s at 6 threads - 6.1%, on top of the batching
work. All 20 scenarios byte-identical at every thread count, in both the normal regime and one with
each job made eight times dearer.
threads: auto stays at the core count. A cap looked right on a fast machine, where the curve peaks
below it, but in the kernel-heavy regime the curve stops turning over - capping at 4 would cost 10.7%
there against 1.3% for no cap at all. resolve_batch_threads carries the numbers.
No ABI or parity bump: results are unchanged, so an older binary still loads and runs correctly.
All six shipped binaries rebuilt.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* test(kernel): skip the pool tests when the binary predates pk_run_batch
The batch and pool tests call run_prediction_kernel_batch, which returns None when the loaded binary
has no pk_run_batch. Four of them treated that as a failure rather than a skip, so running against an
older binary reported errors instead of degrading the way the product does.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: update prediction kernel binaries for all platforms
* fix(kernel): include <system_error> explicitly
The pool catches std::system_error when the system refuses a thread. libc++ pulls that declaration in
through <thread>, libstdc++ does not, so the file built on macOS and failed on GCC with a parse error
at the catch clause. Caught by CI, which builds natively with g++; neither the local clang build nor
the zig cross-build sees it, since both use libc++.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: update prediction kernel binaries for all platforms
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>1 parent 9546ffe commit be9c495
12 files changed
Lines changed: 901 additions & 22 deletions
File tree
- .cspell
- apps/predbat
- tests
- docs/superpowers/specs
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
28 | 29 | | |
29 | 30 | | |
30 | 31 | | |
| |||
380 | 381 | | |
381 | 382 | | |
382 | 383 | | |
| 384 | + | |
383 | 385 | | |
384 | 386 | | |
385 | 387 | | |
| |||
537 | 539 | | |
538 | 540 | | |
539 | 541 | | |
| 542 | + | |
540 | 543 | | |
541 | 544 | | |
542 | 545 | | |
543 | 546 | | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
544 | 550 | | |
545 | 551 | | |
546 | 552 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
38 | 58 | | |
39 | 59 | | |
40 | 60 | | |
| |||
1306 | 1326 | | |
1307 | 1327 | | |
1308 | 1328 | | |
1309 | | - | |
1310 | | - | |
1311 | | - | |
1312 | | - | |
1313 | | - | |
| 1329 | + | |
1314 | 1330 | | |
1315 | 1331 | | |
1316 | 1332 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
| 20 | + | |
19 | 21 | | |
20 | 22 | | |
21 | 23 | | |
| |||
25 | 27 | | |
26 | 28 | | |
27 | 29 | | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
28 | 33 | | |
29 | 34 | | |
30 | 35 | | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
31 | 40 | | |
32 | 41 | | |
33 | 42 | | |
| |||
304 | 313 | | |
305 | 314 | | |
306 | 315 | | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
307 | 328 | | |
308 | 329 | | |
309 | 330 | | |
310 | 331 | | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
311 | 337 | | |
312 | 338 | | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
313 | 357 | | |
314 | 358 | | |
315 | 359 | | |
| |||
1281 | 1325 | | |
1282 | 1326 | | |
1283 | 1327 | | |
1284 | | - | |
1285 | | - | |
| 1328 | + | |
1286 | 1329 | | |
1287 | 1330 | | |
1288 | 1331 | | |
| |||
1317 | 1360 | | |
1318 | 1361 | | |
1319 | 1362 | | |
| 1363 | + | |
| 1364 | + | |
| 1365 | + | |
| 1366 | + | |
| 1367 | + | |
| 1368 | + | |
| 1369 | + | |
| 1370 | + | |
| 1371 | + | |
| 1372 | + | |
| 1373 | + | |
| 1374 | + | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
| 1383 | + | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
| 1388 | + | |
| 1389 | + | |
| 1390 | + | |
| 1391 | + | |
| 1392 | + | |
| 1393 | + | |
| 1394 | + | |
| 1395 | + | |
| 1396 | + | |
| 1397 | + | |
| 1398 | + | |
| 1399 | + | |
| 1400 | + | |
| 1401 | + | |
| 1402 | + | |
| 1403 | + | |
| 1404 | + | |
| 1405 | + | |
| 1406 | + | |
| 1407 | + | |
| 1408 | + | |
| 1409 | + | |
| 1410 | + | |
| 1411 | + | |
| 1412 | + | |
| 1413 | + | |
| 1414 | + | |
| 1415 | + | |
| 1416 | + | |
| 1417 | + | |
| 1418 | + | |
| 1419 | + | |
| 1420 | + | |
| 1421 | + | |
| 1422 | + | |
| 1423 | + | |
| 1424 | + | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
| 1432 | + | |
| 1433 | + | |
| 1434 | + | |
| 1435 | + | |
| 1436 | + | |
| 1437 | + | |
| 1438 | + | |
| 1439 | + | |
| 1440 | + | |
| 1441 | + | |
| 1442 | + | |
| 1443 | + | |
| 1444 | + | |
| 1445 | + | |
| 1446 | + | |
| 1447 | + | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
| 1456 | + | |
| 1457 | + | |
| 1458 | + | |
| 1459 | + | |
| 1460 | + | |
| 1461 | + | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
| 1466 | + | |
| 1467 | + | |
| 1468 | + | |
| 1469 | + | |
| 1470 | + | |
| 1471 | + | |
| 1472 | + | |
| 1473 | + | |
| 1474 | + | |
| 1475 | + | |
| 1476 | + | |
| 1477 | + | |
| 1478 | + | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
| 1496 | + | |
| 1497 | + | |
| 1498 | + | |
| 1499 | + | |
| 1500 | + | |
| 1501 | + | |
| 1502 | + | |
| 1503 | + | |
| 1504 | + | |
| 1505 | + | |
| 1506 | + | |
| 1507 | + | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
| 1512 | + | |
| 1513 | + | |
| 1514 | + | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
| 1522 | + | |
| 1523 | + | |
| 1524 | + | |
| 1525 | + | |
| 1526 | + | |
1320 | 1527 | | |
1321 | 1528 | | |
1322 | 1529 | | |
| |||
1338 | 1545 | | |
1339 | 1546 | | |
1340 | 1547 | | |
1341 | | - | |
1342 | | - | |
1343 | | - | |
1344 | | - | |
1345 | | - | |
1346 | | - | |
1347 | | - | |
1348 | | - | |
1349 | | - | |
1350 | | - | |
| 1548 | + | |
| 1549 | + | |
| 1550 | + | |
| 1551 | + | |
| 1552 | + | |
| 1553 | + | |
| 1554 | + | |
| 1555 | + | |
1351 | 1556 | | |
1352 | | - | |
1353 | | - | |
| 1557 | + | |
| 1558 | + | |
| 1559 | + | |
1354 | 1560 | | |
1355 | | - | |
| 1561 | + | |
1356 | 1562 | | |
1357 | | - | |
1358 | 1563 | | |
1359 | | - | |
| 1564 | + | |
1360 | 1565 | | |
1361 | 1566 | | |
1362 | 1567 | | |
1363 | 1568 | | |
1364 | 1569 | | |
| 1570 | + | |
| 1571 | + | |
| 1572 | + | |
| 1573 | + | |
| 1574 | + | |
| 1575 | + | |
| 1576 | + | |
| 1577 | + | |
| 1578 | + | |
| 1579 | + | |
| 1580 | + | |
| 1581 | + | |
| 1582 | + | |
| 1583 | + | |
| 1584 | + | |
| 1585 | + | |
| 1586 | + | |
| 1587 | + | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
| 1591 | + | |
1365 | 1592 | | |
1366 | 1593 | | |
1367 | 1594 | | |
| |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
0 commit comments