-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Run GC on multiple threads #48600
Run GC on multiple threads #48600
Conversation
abe4675
to
145db71
Compare
I assume this depends on #48123 for good performance on AMD? |
The number of GC threads can be specified through It would be nice to run CI with multiple GC threads (worst case, I think we can chose a higher default count of GC threads for testing purposes). |
Same for PkgEval. |
You can do: |
5489db2
to
9698e23
Compare
The |
33137cf
to
88ebe01
Compare
@nanosoldier |
Your package evaluation job has completed - possible new issues were detected. |
dc2c305
to
40c9618
Compare
3624656
to
b5b5791
Compare
…alse-sharing (#52994) For some reason this only shows up in the `many_refs.jl` benchmark, since it's the only one that hammers the work-stealing queue (we also didn't test this benchmark on a large number of GC threads in our [previous analysis](#48600 (comment))). - master: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4268 │ 3243 │ 3048 │ 194 │ 1126 │ 15 │ 868 │ 76 │ │ median │ 4270 │ 3246 │ 3051 │ 195 │ 1128 │ 17 │ 868 │ 76 │ │ maximum │ 4278 │ 3247 │ 3052 │ 195 │ 1128 │ 18 │ 868 │ 76 │ │ stdev │ 5 │ 2 │ 2 │ 0 │ 1 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2728 │ 1692 │ 1551 │ 141 │ 598 │ 23 │ 868 │ 62 │ │ median │ 2732 │ 1709 │ 1567 │ 141 │ 603 │ 23 │ 868 │ 62 │ │ maximum │ 2744 │ 1712 │ 1571 │ 143 │ 607 │ 24 │ 868 │ 63 │ │ stdev │ 6 │ 9 │ 9 │ 1 │ 4 │ 0 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2105 │ 1082 │ 987 │ 95 │ 405 │ 23 │ 875 │ 51 │ │ median │ 2115 │ 1089 │ 994 │ 95 │ 409 │ 23 │ 875 │ 52 │ │ maximum │ 2127 │ 1100 │ 1003 │ 97 │ 417 │ 25 │ 875 │ 52 │ │ stdev │ 8 │ 8 │ 7 │ 1 │ 5 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 3861 │ 2755 │ 2676 │ 79 │ 1301 │ 22 │ 878 │ 68 │ │ median │ 3864 │ 2835 │ 2756 │ 80 │ 1342 │ 25 │ 879 │ 73 │ │ maximum │ 4032 │ 2877 │ 2797 │ 80 │ 1378 │ 26 │ 880 │ 74 │ │ stdev │ 73 │ 45 │ 45 │ 1 │ 28 │ 2 │ 1 │ 2 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 7455 │ 6425 │ 6344 │ 80 │ 3262 │ 24 │ 882 │ 86 │ │ median │ 7703 │ 6682 │ 6602 │ 81 │ 3313 │ 25 │ 884 │ 87 │ │ maximum │ 7826 │ 6806 │ 6725 │ 81 │ 3422 │ 27 │ 887 │ 87 │ │ stdev │ 152 │ 153 │ 153 │ 0 │ 68 │ 1 │ 2 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ``` - PR: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4264 │ 3240 │ 3048 │ 192 │ 1127 │ 15 │ 868 │ 76 │ │ median │ 4271 │ 3244 │ 3052 │ 192 │ 1129 │ 17 │ 868 │ 76 │ │ maximum │ 4514 │ 3481 │ 3289 │ 193 │ 1247 │ 18 │ 868 │ 77 │ │ stdev │ 109 │ 106 │ 106 │ 0 │ 53 │ 1 │ 0 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2712 │ 1680 │ 1541 │ 138 │ 591 │ 22 │ 868 │ 62 │ │ median │ 2713 │ 1691 │ 1552 │ 140 │ 594 │ 24 │ 868 │ 62 │ │ maximum │ 2732 │ 1710 │ 1569 │ 141 │ 606 │ 25 │ 868 │ 63 │ │ stdev │ 11 │ 12 │ 12 │ 1 │ 6 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2090 │ 1057 │ 962 │ 95 │ 398 │ 22 │ 874 │ 50 │ │ median │ 2103 │ 1070 │ 974 │ 95 │ 401 │ 24 │ 874 │ 51 │ │ maximum │ 2140 │ 1074 │ 978 │ 96 │ 402 │ 25 │ 875 │ 51 │ │ stdev │ 19 │ 6 │ 6 │ 0 │ 1 │ 1 │ 1 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2236 │ 1208 │ 1129 │ 79 │ 528 │ 23 │ 880 │ 54 │ │ median │ 2238 │ 1214 │ 1135 │ 79 │ 533 │ 23 │ 880 │ 54 │ │ maximum │ 2246 │ 1218 │ 1138 │ 80 │ 534 │ 35 │ 880 │ 54 │ │ stdev │ 4 │ 4 │ 4 │ 0 │ 3 │ 5 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2326 │ 1297 │ 1216 │ 80 │ 595 │ 24 │ 884 │ 56 │ │ median │ 2348 │ 1325 │ 1245 │ 80 │ 620 │ 25 │ 885 │ 56 │ │ maximum │ 2370 │ 1341 │ 1262 │ 81 │ 631 │ 26 │ 887 │ 57 │ │ stdev │ 17 │ 19 │ 19 │ 0 │ 14 │ 1 │ 1 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ```
…alse-sharing (JuliaLang#52994) For some reason this only shows up in the `many_refs.jl` benchmark, since it's the only one that hammers the work-stealing queue (we also didn't test this benchmark on a large number of GC threads in our [previous analysis](JuliaLang#48600 (comment))). - master: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4268 │ 3243 │ 3048 │ 194 │ 1126 │ 15 │ 868 │ 76 │ │ median │ 4270 │ 3246 │ 3051 │ 195 │ 1128 │ 17 │ 868 │ 76 │ │ maximum │ 4278 │ 3247 │ 3052 │ 195 │ 1128 │ 18 │ 868 │ 76 │ │ stdev │ 5 │ 2 │ 2 │ 0 │ 1 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2728 │ 1692 │ 1551 │ 141 │ 598 │ 23 │ 868 │ 62 │ │ median │ 2732 │ 1709 │ 1567 │ 141 │ 603 │ 23 │ 868 │ 62 │ │ maximum │ 2744 │ 1712 │ 1571 │ 143 │ 607 │ 24 │ 868 │ 63 │ │ stdev │ 6 │ 9 │ 9 │ 1 │ 4 │ 0 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2105 │ 1082 │ 987 │ 95 │ 405 │ 23 │ 875 │ 51 │ │ median │ 2115 │ 1089 │ 994 │ 95 │ 409 │ 23 │ 875 │ 52 │ │ maximum │ 2127 │ 1100 │ 1003 │ 97 │ 417 │ 25 │ 875 │ 52 │ │ stdev │ 8 │ 8 │ 7 │ 1 │ 5 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 3861 │ 2755 │ 2676 │ 79 │ 1301 │ 22 │ 878 │ 68 │ │ median │ 3864 │ 2835 │ 2756 │ 80 │ 1342 │ 25 │ 879 │ 73 │ │ maximum │ 4032 │ 2877 │ 2797 │ 80 │ 1378 │ 26 │ 880 │ 74 │ │ stdev │ 73 │ 45 │ 45 │ 1 │ 28 │ 2 │ 1 │ 2 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 7455 │ 6425 │ 6344 │ 80 │ 3262 │ 24 │ 882 │ 86 │ │ median │ 7703 │ 6682 │ 6602 │ 81 │ 3313 │ 25 │ 884 │ 87 │ │ maximum │ 7826 │ 6806 │ 6725 │ 81 │ 3422 │ 27 │ 887 │ 87 │ │ stdev │ 152 │ 153 │ 153 │ 0 │ 68 │ 1 │ 2 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ``` - PR: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4264 │ 3240 │ 3048 │ 192 │ 1127 │ 15 │ 868 │ 76 │ │ median │ 4271 │ 3244 │ 3052 │ 192 │ 1129 │ 17 │ 868 │ 76 │ │ maximum │ 4514 │ 3481 │ 3289 │ 193 │ 1247 │ 18 │ 868 │ 77 │ │ stdev │ 109 │ 106 │ 106 │ 0 │ 53 │ 1 │ 0 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2712 │ 1680 │ 1541 │ 138 │ 591 │ 22 │ 868 │ 62 │ │ median │ 2713 │ 1691 │ 1552 │ 140 │ 594 │ 24 │ 868 │ 62 │ │ maximum │ 2732 │ 1710 │ 1569 │ 141 │ 606 │ 25 │ 868 │ 63 │ │ stdev │ 11 │ 12 │ 12 │ 1 │ 6 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2090 │ 1057 │ 962 │ 95 │ 398 │ 22 │ 874 │ 50 │ │ median │ 2103 │ 1070 │ 974 │ 95 │ 401 │ 24 │ 874 │ 51 │ │ maximum │ 2140 │ 1074 │ 978 │ 96 │ 402 │ 25 │ 875 │ 51 │ │ stdev │ 19 │ 6 │ 6 │ 0 │ 1 │ 1 │ 1 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2236 │ 1208 │ 1129 │ 79 │ 528 │ 23 │ 880 │ 54 │ │ median │ 2238 │ 1214 │ 1135 │ 79 │ 533 │ 23 │ 880 │ 54 │ │ maximum │ 2246 │ 1218 │ 1138 │ 80 │ 534 │ 35 │ 880 │ 54 │ │ stdev │ 4 │ 4 │ 4 │ 0 │ 3 │ 5 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2326 │ 1297 │ 1216 │ 80 │ 595 │ 24 │ 884 │ 56 │ │ median │ 2348 │ 1325 │ 1245 │ 80 │ 620 │ 25 │ 885 │ 56 │ │ maximum │ 2370 │ 1341 │ 1262 │ 81 │ 631 │ 26 │ 887 │ 57 │ │ stdev │ 17 │ 19 │ 19 │ 0 │ 14 │ 1 │ 1 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ```
…alse-sharing (JuliaLang#52994) For some reason this only shows up in the `many_refs.jl` benchmark, since it's the only one that hammers the work-stealing queue (we also didn't test this benchmark on a large number of GC threads in our [previous analysis](JuliaLang#48600 (comment))). - master: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4268 │ 3243 │ 3048 │ 194 │ 1126 │ 15 │ 868 │ 76 │ │ median │ 4270 │ 3246 │ 3051 │ 195 │ 1128 │ 17 │ 868 │ 76 │ │ maximum │ 4278 │ 3247 │ 3052 │ 195 │ 1128 │ 18 │ 868 │ 76 │ │ stdev │ 5 │ 2 │ 2 │ 0 │ 1 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2728 │ 1692 │ 1551 │ 141 │ 598 │ 23 │ 868 │ 62 │ │ median │ 2732 │ 1709 │ 1567 │ 141 │ 603 │ 23 │ 868 │ 62 │ │ maximum │ 2744 │ 1712 │ 1571 │ 143 │ 607 │ 24 │ 868 │ 63 │ │ stdev │ 6 │ 9 │ 9 │ 1 │ 4 │ 0 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2105 │ 1082 │ 987 │ 95 │ 405 │ 23 │ 875 │ 51 │ │ median │ 2115 │ 1089 │ 994 │ 95 │ 409 │ 23 │ 875 │ 52 │ │ maximum │ 2127 │ 1100 │ 1003 │ 97 │ 417 │ 25 │ 875 │ 52 │ │ stdev │ 8 │ 8 │ 7 │ 1 │ 5 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 3861 │ 2755 │ 2676 │ 79 │ 1301 │ 22 │ 878 │ 68 │ │ median │ 3864 │ 2835 │ 2756 │ 80 │ 1342 │ 25 │ 879 │ 73 │ │ maximum │ 4032 │ 2877 │ 2797 │ 80 │ 1378 │ 26 │ 880 │ 74 │ │ stdev │ 73 │ 45 │ 45 │ 1 │ 28 │ 2 │ 1 │ 2 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 7455 │ 6425 │ 6344 │ 80 │ 3262 │ 24 │ 882 │ 86 │ │ median │ 7703 │ 6682 │ 6602 │ 81 │ 3313 │ 25 │ 884 │ 87 │ │ maximum │ 7826 │ 6806 │ 6725 │ 81 │ 3422 │ 27 │ 887 │ 87 │ │ stdev │ 152 │ 153 │ 153 │ 0 │ 68 │ 1 │ 2 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ``` - PR: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4264 │ 3240 │ 3048 │ 192 │ 1127 │ 15 │ 868 │ 76 │ │ median │ 4271 │ 3244 │ 3052 │ 192 │ 1129 │ 17 │ 868 │ 76 │ │ maximum │ 4514 │ 3481 │ 3289 │ 193 │ 1247 │ 18 │ 868 │ 77 │ │ stdev │ 109 │ 106 │ 106 │ 0 │ 53 │ 1 │ 0 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2712 │ 1680 │ 1541 │ 138 │ 591 │ 22 │ 868 │ 62 │ │ median │ 2713 │ 1691 │ 1552 │ 140 │ 594 │ 24 │ 868 │ 62 │ │ maximum │ 2732 │ 1710 │ 1569 │ 141 │ 606 │ 25 │ 868 │ 63 │ │ stdev │ 11 │ 12 │ 12 │ 1 │ 6 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2090 │ 1057 │ 962 │ 95 │ 398 │ 22 │ 874 │ 50 │ │ median │ 2103 │ 1070 │ 974 │ 95 │ 401 │ 24 │ 874 │ 51 │ │ maximum │ 2140 │ 1074 │ 978 │ 96 │ 402 │ 25 │ 875 │ 51 │ │ stdev │ 19 │ 6 │ 6 │ 0 │ 1 │ 1 │ 1 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2236 │ 1208 │ 1129 │ 79 │ 528 │ 23 │ 880 │ 54 │ │ median │ 2238 │ 1214 │ 1135 │ 79 │ 533 │ 23 │ 880 │ 54 │ │ maximum │ 2246 │ 1218 │ 1138 │ 80 │ 534 │ 35 │ 880 │ 54 │ │ stdev │ 4 │ 4 │ 4 │ 0 │ 3 │ 5 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2326 │ 1297 │ 1216 │ 80 │ 595 │ 24 │ 884 │ 56 │ │ median │ 2348 │ 1325 │ 1245 │ 80 │ 620 │ 25 │ 885 │ 56 │ │ maximum │ 2370 │ 1341 │ 1262 │ 81 │ 631 │ 26 │ 887 │ 57 │ │ stdev │ 17 │ 19 │ 19 │ 0 │ 14 │ 1 │ 1 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ```
…alse-sharing (#52994) For some reason this only shows up in the `many_refs.jl` benchmark, since it's the only one that hammers the work-stealing queue (we also didn't test this benchmark on a large number of GC threads in our [previous analysis](#48600 (comment))). - master: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4268 │ 3243 │ 3048 │ 194 │ 1126 │ 15 │ 868 │ 76 │ │ median │ 4270 │ 3246 │ 3051 │ 195 │ 1128 │ 17 │ 868 │ 76 │ │ maximum │ 4278 │ 3247 │ 3052 │ 195 │ 1128 │ 18 │ 868 │ 76 │ │ stdev │ 5 │ 2 │ 2 │ 0 │ 1 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2728 │ 1692 │ 1551 │ 141 │ 598 │ 23 │ 868 │ 62 │ │ median │ 2732 │ 1709 │ 1567 │ 141 │ 603 │ 23 │ 868 │ 62 │ │ maximum │ 2744 │ 1712 │ 1571 │ 143 │ 607 │ 24 │ 868 │ 63 │ │ stdev │ 6 │ 9 │ 9 │ 1 │ 4 │ 0 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2105 │ 1082 │ 987 │ 95 │ 405 │ 23 │ 875 │ 51 │ │ median │ 2115 │ 1089 │ 994 │ 95 │ 409 │ 23 │ 875 │ 52 │ │ maximum │ 2127 │ 1100 │ 1003 │ 97 │ 417 │ 25 │ 875 │ 52 │ │ stdev │ 8 │ 8 │ 7 │ 1 │ 5 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 3861 │ 2755 │ 2676 │ 79 │ 1301 │ 22 │ 878 │ 68 │ │ median │ 3864 │ 2835 │ 2756 │ 80 │ 1342 │ 25 │ 879 │ 73 │ │ maximum │ 4032 │ 2877 │ 2797 │ 80 │ 1378 │ 26 │ 880 │ 74 │ │ stdev │ 73 │ 45 │ 45 │ 1 │ 28 │ 2 │ 1 │ 2 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 7455 │ 6425 │ 6344 │ 80 │ 3262 │ 24 │ 882 │ 86 │ │ median │ 7703 │ 6682 │ 6602 │ 81 │ 3313 │ 25 │ 884 │ 87 │ │ maximum │ 7826 │ 6806 │ 6725 │ 81 │ 3422 │ 27 │ 887 │ 87 │ │ stdev │ 152 │ 153 │ 153 │ 0 │ 68 │ 1 │ 2 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ``` - PR: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4264 │ 3240 │ 3048 │ 192 │ 1127 │ 15 │ 868 │ 76 │ │ median │ 4271 │ 3244 │ 3052 │ 192 │ 1129 │ 17 │ 868 │ 76 │ │ maximum │ 4514 │ 3481 │ 3289 │ 193 │ 1247 │ 18 │ 868 │ 77 │ │ stdev │ 109 │ 106 │ 106 │ 0 │ 53 │ 1 │ 0 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2712 │ 1680 │ 1541 │ 138 │ 591 │ 22 │ 868 │ 62 │ │ median │ 2713 │ 1691 │ 1552 │ 140 │ 594 │ 24 │ 868 │ 62 │ │ maximum │ 2732 │ 1710 │ 1569 │ 141 │ 606 │ 25 │ 868 │ 63 │ │ stdev │ 11 │ 12 │ 12 │ 1 │ 6 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2090 │ 1057 │ 962 │ 95 │ 398 │ 22 │ 874 │ 50 │ │ median │ 2103 │ 1070 │ 974 │ 95 │ 401 │ 24 │ 874 │ 51 │ │ maximum │ 2140 │ 1074 │ 978 │ 96 │ 402 │ 25 │ 875 │ 51 │ │ stdev │ 19 │ 6 │ 6 │ 0 │ 1 │ 1 │ 1 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2236 │ 1208 │ 1129 │ 79 │ 528 │ 23 │ 880 │ 54 │ │ median │ 2238 │ 1214 │ 1135 │ 79 │ 533 │ 23 │ 880 │ 54 │ │ maximum │ 2246 │ 1218 │ 1138 │ 80 │ 534 │ 35 │ 880 │ 54 │ │ stdev │ 4 │ 4 │ 4 │ 0 │ 3 │ 5 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2326 │ 1297 │ 1216 │ 80 │ 595 │ 24 │ 884 │ 56 │ │ median │ 2348 │ 1325 │ 1245 │ 80 │ 620 │ 25 │ 885 │ 56 │ │ maximum │ 2370 │ 1341 │ 1262 │ 81 │ 631 │ 26 │ 887 │ 57 │ │ stdev │ 17 │ 19 │ 19 │ 0 │ 14 │ 1 │ 1 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ``` (cherry picked from commit 9f36490)
Using a work-stealing queue after Chase and Lev, optimized for weak memory models by Le et al. Default number of GC threads is half the number of compute threads. Co-authored-by: Gabriel Baraldi <baraldigabriel@gmail.com> Co-authored-by: Valentin Churavy <v.churavy@gmail.com>
…alse-sharing (JuliaLang#52994) For some reason this only shows up in the `many_refs.jl` benchmark, since it's the only one that hammers the work-stealing queue (we also didn't test this benchmark on a large number of GC threads in our [previous analysis](JuliaLang#48600 (comment))). - master: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4268 │ 3243 │ 3048 │ 194 │ 1126 │ 15 │ 868 │ 76 │ │ median │ 4270 │ 3246 │ 3051 │ 195 │ 1128 │ 17 │ 868 │ 76 │ │ maximum │ 4278 │ 3247 │ 3052 │ 195 │ 1128 │ 18 │ 868 │ 76 │ │ stdev │ 5 │ 2 │ 2 │ 0 │ 1 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2728 │ 1692 │ 1551 │ 141 │ 598 │ 23 │ 868 │ 62 │ │ median │ 2732 │ 1709 │ 1567 │ 141 │ 603 │ 23 │ 868 │ 62 │ │ maximum │ 2744 │ 1712 │ 1571 │ 143 │ 607 │ 24 │ 868 │ 63 │ │ stdev │ 6 │ 9 │ 9 │ 1 │ 4 │ 0 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2105 │ 1082 │ 987 │ 95 │ 405 │ 23 │ 875 │ 51 │ │ median │ 2115 │ 1089 │ 994 │ 95 │ 409 │ 23 │ 875 │ 52 │ │ maximum │ 2127 │ 1100 │ 1003 │ 97 │ 417 │ 25 │ 875 │ 52 │ │ stdev │ 8 │ 8 │ 7 │ 1 │ 5 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 3861 │ 2755 │ 2676 │ 79 │ 1301 │ 22 │ 878 │ 68 │ │ median │ 3864 │ 2835 │ 2756 │ 80 │ 1342 │ 25 │ 879 │ 73 │ │ maximum │ 4032 │ 2877 │ 2797 │ 80 │ 1378 │ 26 │ 880 │ 74 │ │ stdev │ 73 │ 45 │ 45 │ 1 │ 28 │ 2 │ 1 │ 2 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 7455 │ 6425 │ 6344 │ 80 │ 3262 │ 24 │ 882 │ 86 │ │ median │ 7703 │ 6682 │ 6602 │ 81 │ 3313 │ 25 │ 884 │ 87 │ │ maximum │ 7826 │ 6806 │ 6725 │ 81 │ 3422 │ 27 │ 887 │ 87 │ │ stdev │ 152 │ 153 │ 153 │ 0 │ 68 │ 1 │ 2 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ``` - PR: ``` bench = "many_refs.jl" (gcthreads, threads) = (1, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 4264 │ 3240 │ 3048 │ 192 │ 1127 │ 15 │ 868 │ 76 │ │ median │ 4271 │ 3244 │ 3052 │ 192 │ 1129 │ 17 │ 868 │ 76 │ │ maximum │ 4514 │ 3481 │ 3289 │ 193 │ 1247 │ 18 │ 868 │ 77 │ │ stdev │ 109 │ 106 │ 106 │ 0 │ 53 │ 1 │ 0 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (2, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2712 │ 1680 │ 1541 │ 138 │ 591 │ 22 │ 868 │ 62 │ │ median │ 2713 │ 1691 │ 1552 │ 140 │ 594 │ 24 │ 868 │ 62 │ │ maximum │ 2732 │ 1710 │ 1569 │ 141 │ 606 │ 25 │ 868 │ 63 │ │ stdev │ 11 │ 12 │ 12 │ 1 │ 6 │ 1 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (4, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2090 │ 1057 │ 962 │ 95 │ 398 │ 22 │ 874 │ 50 │ │ median │ 2103 │ 1070 │ 974 │ 95 │ 401 │ 24 │ 874 │ 51 │ │ maximum │ 2140 │ 1074 │ 978 │ 96 │ 402 │ 25 │ 875 │ 51 │ │ stdev │ 19 │ 6 │ 6 │ 0 │ 1 │ 1 │ 1 │ 1 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (8, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2236 │ 1208 │ 1129 │ 79 │ 528 │ 23 │ 880 │ 54 │ │ median │ 2238 │ 1214 │ 1135 │ 79 │ 533 │ 23 │ 880 │ 54 │ │ maximum │ 2246 │ 1218 │ 1138 │ 80 │ 534 │ 35 │ 880 │ 54 │ │ stdev │ 4 │ 4 │ 4 │ 0 │ 3 │ 5 │ 0 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ (gcthreads, threads) = (16, 1) ┌─────────┬────────────┬─────────┬───────────┬────────────┬──────────────┬───────────────────┬──────────┬────────────┐ │ │ total time │ gc time │ mark time │ sweep time │ max GC pause │ time to safepoint │ max heap │ percent gc │ │ │ ms │ ms │ ms │ ms │ ms │ us │ MB │ % │ ├─────────┼────────────┼─────────┼───────────┼────────────┼──────────────┼───────────────────┼──────────┼────────────┤ │ minimum │ 2326 │ 1297 │ 1216 │ 80 │ 595 │ 24 │ 884 │ 56 │ │ median │ 2348 │ 1325 │ 1245 │ 80 │ 620 │ 25 │ 885 │ 56 │ │ maximum │ 2370 │ 1341 │ 1262 │ 81 │ 631 │ 26 │ 887 │ 57 │ │ stdev │ 17 │ 19 │ 19 │ 0 │ 14 │ 1 │ 1 │ 0 │ └─────────┴────────────┴─────────┴───────────┴────────────┴──────────────┴───────────────────┴──────────┴────────────┘ ``` (cherry picked from commit 9f36490)
Summary
This PR parallelizes the GC mark-loop by introducing GC threads into the Julia runtime and by implementing work-stealing to dynamically balance the amount of work each thread performs in the GC mark-loop.
Implementation
Following #47292, each thread running the GC mark-loop manages two work-queues: one queue stores pointers to Julia objects that need to be scanned, and another queue (chunk queue) stores iterator states corresponding to suffixes of large arrays that need to be scanned.
Both the pointer and chunk queues are lock-free and are based on the work of Chase-Lev and Le et. al (see papers referenced in
work-stealing-queue.h
).Results
These are speedups in mark-time for a tweaked (JuliaCI/GCBenchmarks#61) version of the
rb_tree.jl
benchmark fromGCBenchmarks
. This representative benchmark uses a single mutator thread (we scale the number of GC threads in the plots below). For more benchmarks, see @vchuravy's comment below.Machine
Speedups