diff --git a/doc/devel/dump/2023-12-09.Scheduler-Integration/Dump-04 b/doc/devel/dump/2023-12-09.Scheduler-Integration/Dump-04 new file mode 100644 index 000000000..14a8a1b0f --- /dev/null +++ b/doc/devel/dump/2023-12-09.Scheduler-Integration/Dump-04 @@ -0,0 +1,510 @@ +invokeTestCase: ++------------------- invoking TEST: vault::gear::test::TestChainLoad_test + ++++ 8F: seed(num:64) + +ANCHOR=0 preRoll=5120 +‖▷▷▷‖ 8F: @ -4805 EMPTY +‖IGN‖ wof:8 + +‖SCH‖ 8F: @-3381 ○ start=-4951 dead:100000 +!◆! plan...to:63|curr=0 (max:64) + + |n.(0,lev:0) +... dispose(i=0,lev:0) -> @0 +‖•△•‖ wof:8 HT:195 +‖SCH‖ 8F: @-3186 ○ start=0 dead:10000 + |n.(1,lev:1) +... dispose(i=1,lev:1) -> @1000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-3103 ○ start=1000 dead:10000 + |n.(2,lev:2) +... dispose(i=2,lev:2) -> @2000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-3021 ○ start=2000 dead:10000 + |n.(3,lev:2) +... dispose(i=3,lev:2) -> @2000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2959 ○ start=2000 dead:10000 + |n.(4,lev:3) +... dispose(i=4,lev:3) -> @3000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2895 ○ start=3000 dead:10000 + |n.(5,lev:3) +... dispose(i=5,lev:3) -> @3000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2814 ○ start=3000 dead:10000 + |n.(6,lev:3) +... dispose(i=6,lev:3) -> @3000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2749 ○ start=3000 dead:10000 + |n.(7,lev:4) +... dispose(i=7,lev:4) -> @4000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2686 ○ start=4000 dead:10000 + |n.(8,lev:4) +... dispose(i=8,lev:4) -> @4000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2625 ○ start=4000 dead:10000 + |n.(9,lev:4) +... dispose(i=9,lev:4) -> @4000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2561 ○ start=4000 dead:10000 + |n.(10,lev:4) +... dispose(i=10,lev:4) -> @4000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2496 ○ start=4000 dead:10000 + |n.(11,lev:5) +... dispose(i=11,lev:5) -> @5000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2433 ○ start=5000 dead:10000 + |n.(12,lev:5) +... dispose(i=12,lev:5) -> @5000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2370 ○ start=5000 dead:10000 + |n.(13,lev:5) +... dispose(i=13,lev:5) -> @5000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2307 ○ start=5000 dead:10000 + |n.(14,lev:5) +... dispose(i=14,lev:5) -> @5000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2246 ○ start=5000 dead:10000 + |n.(15,lev:6) +... dispose(i=15,lev:6) -> @6000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2184 ○ start=6000 dead:10000 + |n.(16,lev:6) +... dispose(i=16,lev:6) -> @6000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2123 ○ start=6000 dead:10000 + |n.(17,lev:6) +... dispose(i=17,lev:6) -> @6000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2061 ○ start=6000 dead:10000 + |n.(18,lev:6) +... dispose(i=18,lev:6) -> @6000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-2001 ○ start=6000 dead:10000 + |n.(19,lev:6) +... dispose(i=19,lev:6) -> @6000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1889 ○ start=6000 dead:10000 + |n.(20,lev:7) +... dispose(i=20,lev:7) -> @7000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1826 ○ start=7000 dead:10000 + |n.(21,lev:7) +... dispose(i=21,lev:7) -> @7000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1747 ○ start=7000 dead:10000 + |n.(22,lev:7) +... dispose(i=22,lev:7) -> @7000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1670 ○ start=7000 dead:10000 + |n.(23,lev:7) +... dispose(i=23,lev:7) -> @7000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1607 ○ start=7000 dead:10000 + |n.(24,lev:7) +... dispose(i=24,lev:7) -> @7000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1544 ○ start=7000 dead:10000 + |n.(25,lev:8) +... dispose(i=25,lev:8) -> @8000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1483 ○ start=8000 dead:10000 + |n.(26,lev:8) +... dispose(i=26,lev:8) -> @8000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1411 ○ start=8000 dead:10000 + |n.(27,lev:8) +... dispose(i=27,lev:8) -> @8000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1345 ○ start=8000 dead:10000 + |n.(28,lev:8) +... dispose(i=28,lev:8) -> @8000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1268 ○ start=8000 dead:10000 + |n.(29,lev:8) +... dispose(i=29,lev:8) -> @8000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1184 ○ start=8000 dead:10000 + |n.(30,lev:9) +... dispose(i=30,lev:9) -> @9000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1115 ○ start=9000 dead:10000 + |n.(31,lev:9) +... dispose(i=31,lev:9) -> @9000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-1047 ○ start=9000 dead:10000 + |n.(32,lev:9) +... dispose(i=32,lev:9) -> @9000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-980 ○ start=9000 dead:10000 + |n.(33,lev:9) +... dispose(i=33,lev:9) -> @9000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-914 ○ start=9000 dead:10000 + |n.(34,lev:9) +... dispose(i=34,lev:9) -> @9000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-846 ○ start=9000 dead:10000 + |n.(35,lev:10) +... dispose(i=35,lev:10) -> @10000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-773 ○ start=10000 dead:10000 + |n.(36,lev:10) +... dispose(i=36,lev:10) -> @10000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-709 ○ start=10000 dead:10000 + |n.(37,lev:10) +... dispose(i=37,lev:10) -> @10000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-645 ○ start=10000 dead:10000 + |n.(38,lev:10) +... dispose(i=38,lev:10) -> @10000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-585 ○ start=10000 dead:10000 + |n.(39,lev:10) +... dispose(i=39,lev:10) -> @10000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-523 ○ start=10000 dead:10000 + |n.(40,lev:11) +... dispose(i=40,lev:11) -> @11000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-460 ○ start=11000 dead:10000 + |n.(41,lev:11) +... dispose(i=41,lev:11) -> @11000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-398 ○ start=11000 dead:10000 + |n.(42,lev:11) +... dispose(i=42,lev:11) -> @11000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-334 ○ start=11000 dead:10000 + |n.(43,lev:11) +... dispose(i=43,lev:11) -> @11000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-270 ○ start=11000 dead:10000 + |n.(44,lev:11) +... dispose(i=44,lev:11) -> @11000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-207 ○ start=11000 dead:10000 + |n.(45,lev:12) +... dispose(i=45,lev:12) -> @12000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-147 ○ start=12000 dead:10000 + |n.(46,lev:12) +... dispose(i=46,lev:12) -> @12000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-86 ○ start=12000 dead:10000 + |n.(47,lev:12) +... dispose(i=47,lev:12) -> @12000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @-24 ○ start=12000 dead:10000 + |n.(48,lev:12) +... dispose(i=48,lev:12) -> @12000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @36 ○ start=12000 dead:10000 + |n.(49,lev:12) +... dispose(i=49,lev:12) -> @12000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @98 ○ start=12000 dead:10000 + |n.(50,lev:13) +... dispose(i=50,lev:13) -> @13000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @160 ○ start=13000 dead:10000 + |n.(51,lev:13) +... dispose(i=51,lev:13) -> @13000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @222 ○ start=13000 dead:10000 + |n.(52,lev:13) +... dispose(i=52,lev:13) -> @13000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @283 ○ start=13000 dead:10000 + |n.(53,lev:13) +... dispose(i=53,lev:13) -> @13000 +‖•△•‖ wof:8 HT:0 +‖SCH‖ 8F: @359 ○ start=13000 dead:10000 + ·‖ 6A: @ 350 HT:195 -> ▶ 0 + |n.(54,lev:13) + +!◆! 6A: calc(i=0, lev:0) + +... dispose(i=54,lev:13) -> @13000 +‖•△•‖ wof:8 HT:195 +‖SCH‖ 8F: @451 ○ start=13000 dead:10000 + |n.(55,lev:14) +... dispose(i=55,lev:14) -> @14000 +‖•△•‖ wof:8 HT:195 +‖SCH‖ 8F: @520 ○ start=14000 dead:10000 + +!◆! 6A: calc(i=1, lev:1) + + |n.(56,lev:14) +... dispose(i=56,lev:14) -> @14000 +‖•△•‖ wof:8 HT:195 +‖SCH‖ 8F: @612 ○ start=14000 dead:10000 + |n.(57,lev:14) +... dispose(i=57,lev:14) -> @14000 +‖•△•‖ wof:8 HT:195 +‖SCH‖ 8F: @683 ○ start=14000 dead:10000 + +!◆! 6A: calc(i=3, lev:2) + + ·‖ 70: @ 695 HT:1000 -> ▶ 195 +‖▷▷▷‖ 70: @ 764 HT:1000 + + |n.(58,lev:14) +... dispose(i=58,lev:14) -> @14000 +‖•△•‖ wof:8 HT:1000 +‖SCH‖ 8F: @793 ○ start=14000 dead:10000 + +!◆! 6A: calc(i=6, lev:3) + + |n.(59,lev:14) +... dispose(i=59,lev:14) -> @14000 +‖•△•‖ wof:8 HT:1000 +‖SCH‖ 8F: @882 ○ start=14000 dead:10000 + |n.(60,lev:15) +... dispose(i=60,lev:15) -> @15000 +‖•△•‖ wof:8 HT:1000 +‖SCH‖ 8F: @954 ○ start=15000 dead:10000 + +!◆! 6A: calc(i=10, lev:4) + + |n.(61,lev:15) +... dispose(i=61,lev:15) -> @15000 +‖•△•‖ wof:8 HT:1000 +‖SCH‖ 8F: @1043 ○ start=15000 dead:10000 + + ·‖ 70: @ 1063 HT:2000 -> ▶ 1000 + + |n.(62,lev:15) +... dispose(i=62,lev:15) -> @15000 +‖•△•‖ wof:8 HT:2000 +‖SCH‖ 8F: @1127 ○ start=15000 dead:10000 + +!◆! 6A: calc(i=14, lev:5) + + |n.(63,lev:16) +... dispose(i=63,lev:16) -> @16000 +‖•△•‖ wof:8 HT:2000 +‖SCH‖ 8F: @1217 ○ start=16000 dead:10000 + ++++ 8F: Continuation(lastNode=63, levelDone=16, work_left:false) +‖•△•‖ wof:8 HT:2000 +‖SCH‖ 8F: @1320 ○ start=17000 dead:100000 + +!◆! 6A: calc(i=19, lev:6) + + ·‖ 70: @ 2084 HT:2000 -> ▶ 2000 + ·‖ 70: @ 2119 HT:3000 -> ▶ 2000 + +!◆! 70: calc(i=2, lev:2) +!◆! 70: calc(i=4, lev:3) + + ·‖ 70: @ 3061 HT:3000 -> ▶ 3000 + +!◆! 70: calc(i=5, lev:3) +!◆! 70: calc(i=8, lev:4) + + ·‖ 70: @ 3441 HT:3000 -> ▶ 3000 + ·‖ 70: @ 3464 HT:4000 -> ▶ 3000 + ·‖ 70: @ 4130 HT:4000 -> ▶ 4000 + ·‖ 70: @ 4192 HT:4000 -> ▶ 4000 + +!◆! 70: calc(i=9, lev:4) +!◆! 70: calc(i=12, lev:5) + + ·‖ 70: @ 4596 HT:4000 -> ▶ 4000 + ·‖ 70: @ 4619 HT:5000 -> ▶ 4000 + +!◆! 70: calc(i=7, lev:4) +!◆! 70: calc(i=11, lev:5) +!◆! 70: calc(i=16, lev:6) + + ·‖ 98: @ 5008 HT:5000 -> ▶ 5000 + +!◆! 98: calc(i=13, lev:5) + + ·‖ 74: @ 5106 HT:5000 -> ▶ 5000 + ·‖ 70: @ 5212 HT:5000 -> ∘ + ·‖ 98: @ 5248 HT:5000 -> ∘ + ·‖ 70: @ 5258 HT:5000 -> ∘ + ·‖ 98: @ 5265 HT:5000 -> ∘ + ·‖ 70: @ 5284 HT:5000 -> ∘ + ·‖ 74: @ 5271 HT:5000 -> ▶ 5000 + ·‖ 98: @ 5291 HT:5000 -> ∘ + ·‖ 70: @ 5319 HT:5000 -> ∘ + ·‖ 98: @ 5352 HT:5000 -> ∘ + ·‖ 74: @ 5353 HT:5239 -> ▶ 5000 + ·‖ 70: @ 5362 HT:5239 -> ∘ + ·‖ 98: @ 5366 HT:5239 -> ∘ + ·‖ 70: @ 5385 HT:5239 -> ∘ + ·‖ 70: @ 5430 HT:5239 -> ∘ + ·‖ 98: @ 5432 HT:5239 -> ∘ + ·‖ 74: @ 5433 HT:6000 -> ▶ 5239 + +!◆! 74: calc(i=18, lev:6) +!◆! 74: calc(i=23, lev:7) + + ·‖ C2: @ 6021 HT:6000 -> ▶ 6000 + ·‖ 98: @ 6023 HT:6000 -> ∘ + ·‖ C2: @ 6048 HT:6000 -> ▶ 6000 + ·‖ C2: @ 6064 HT:6000 -> ▶ 6000 + ·‖ 98: @ 6064 HT:6000 -> ∘ + ·‖ 74: @ 6073 HT:6000 -> ∘ + ·‖ 70: @ 6066 HT:6000 -> ∘ + ·‖ 74: @ 6110 HT:6000 -> ▶ 6000 + ·‖ 70: @ 6134 HT:6000 -> ∘ + +!◆! C2: calc(i=17, lev:6) + + ·‖ 98: @ 6121 HT:6000 -> ∘ + ·‖ 70: @ 6157 HT:6000 -> ∘ + ·‖ 74: @ 6185 HT:7000 -> ▶ 6000 + +!◆! 74: calc(i=15, lev:6) +!◆! C2: calc(i=21, lev:7) +!◆! 74: calc(i=20, lev:7) +!◆! 74: calc(i=26, lev:8) + + ·‖ 74: @ 7003 HT:7000 -> ▶ 7000 + +!◆! 74: calc(i=24, lev:7) + + ·‖ 98: @ 7064 HT:7000 -> ∘ + ·‖ 70: @ 7064 HT:7000 -> ▶ 7000 + ·‖ 70: @ 7094 HT:7000 -> ▶ 7000 + ·‖ 98: @ 7129 HT:7000 -> ▶ 7000 + +!◆! 70: calc(i=22, lev:7) + + ·‖ 98: @ 7157 HT:8000 -> ▶ 7000 + +!◆! 74: calc(i=29, lev:8) +!◆! 70: calc(i=28, lev:8) +!◆! 74: calc(i=33, lev:9) + + ·‖ 98: @ 8060 HT:8000 -> ▶ 8000 + ·‖ 98: @ 8086 HT:8000 -> ▶ 8000 + ·‖ 98: @ 8107 HT:8000 -> ▶ 8000 + +!◆! 98: calc(i=27, lev:8) +!◆! 98: calc(i=31, lev:9) + + ·‖ 98: @ 8485 HT:8000 -> ▶ 8000 + ·‖ 98: @ 8506 HT:9000 -> ▶ 8000 + +!◆! 98: calc(i=25, lev:8) +!◆! 98: calc(i=30, lev:9) +!◆! 98: calc(i=36, lev:10) + + ·‖ 98: @ 9065 HT:9000 -> ∘ + ·‖ 98: @ 9082 HT:9000 -> ∘ + ·‖ D4: @ 9064 HT:9000 -> ▶ 9000 + +!◆! D4: calc(i=34, lev:9) + + ·‖ 98: @ 9101 HT:9000 -> ∘ + ·‖ 98: @ 9127 HT:9000 -> ▶ 9000 + ·‖ 98: @ 9158 HT:9000 -> ▶ 9000 + +!◆! 98: calc(i=32, lev:9) +!◆! D4: calc(i=39, lev:10) +!◆! 98: calc(i=38, lev:10) + + ·‖ D4: @ 9508 HT:9000 -> ▶ 9000 + ·‖ D4: @ 9530 HT:10000 -> ▶ 9000 + +!◆! 98: calc(i=43, lev:11) + + ·‖ D4: @ 10063 HT:10000 -> ▶ 10000 + ·‖ D4: @ 10084 HT:10000 -> ▶ 10000 + ·‖ D4: @ 10101 HT:10000 -> ▶ 10000 + +!◆! D4: calc(i=37, lev:10) +!◆! D4: calc(i=41, lev:11) + + ·‖ D4: @ 10416 HT:10000 -> ▶ 10000 + ·‖ D4: @ 10435 HT:11000 -> ▶ 10000 + +!◆! D4: calc(i=35, lev:10) +!◆! D4: calc(i=40, lev:11) +!◆! D4: calc(i=46, lev:12) + + ·‖ 70: @ 11064 HT:11000 -> ▶ 11000 + ·‖ 70: @ 11096 HT:11000 -> ▶ 11000 + +!◆! 70: calc(i=44, lev:11) +!◆! 70: calc(i=49, lev:12) + + ·‖ C2: @ 11487 HT:11000 -> ∘ + ·‖ 70: @ 11489 HT:11000 -> ▶ 11000 + ·‖ 70: @ 11520 HT:11000 -> ▶ 11000 + ·‖ C2: @ 11547 HT:11000 -> ∘ + ·‖ 70: @ 11559 HT:12000 -> ▶ 11000 + +!◆! 70: calc(i=42, lev:11) +!◆! 70: calc(i=48, lev:12) +!◆! 70: calc(i=53, lev:13) + + ·‖ C2: @ 12060 HT:12000 -> ▶ 12000 + ·‖ C2: @ 12081 HT:12000 -> ▶ 12000 + ·‖ C2: @ 12098 HT:12000 -> ▶ 12000 + ·‖ 70: @ 12120 HT:12000 -> ▶ 12000 + +!◆! 70: calc(i=45, lev:12) +!◆! C2: calc(i=47, lev:12) +!◆! C2: calc(i=51, lev:13) +!◆! 70: calc(i=50, lev:13) +!◆! 70: calc(i=56, lev:14) + + ·‖ C2: @ 12387 HT:13000 -> ▶ 12000 + ·‖ C2: @ 13060 HT:13000 -> ▶ 13000 + ·‖ C2: @ 13080 HT:13000 -> ▶ 13000 + +!◆! C2: calc(i=54, lev:13) +!◆! C2: calc(i=59, lev:14) + + ·‖ C2: @ 13366 HT:13000 -> ▶ 13000 + ·‖ C2: @ 13383 HT:13000 -> ▶ 13000 + ·‖ C2: @ 13400 HT:14000 -> ▶ 13000 + +!◆! C2: calc(i=52, lev:13) +!◆! C2: calc(i=58, lev:14) +!◆! C2: calc(i=62, lev:15) + + ·‖ C2: @ 14059 HT:14000 -> ▶ 14000 + ·‖ C2: @ 14078 HT:14000 -> ▶ 14000 + ·‖ C2: @ 14095 HT:14000 -> ▶ 14000 + +!◆! C2: calc(i=57, lev:14) + + ·‖ 74: @ 14144 HT:14000 -> ▶ 14000 + +!◆! 74: calc(i=55, lev:14) +!◆! C2: calc(i=61, lev:15) +!◆! 74: calc(i=60, lev:15) + + ·‖ C2: @ 14367 HT:15000 -> ▶ 14000 + +!◆! 74: calc(i=63, lev:16) + + ·‖ C2: @ 15060 HT:15000 -> ▶ 15000 + ·‖ C2: @ 15080 HT:15000 -> ▶ 15000 + ·‖ C2: @ 15097 HT:16000 -> ▶ 15000 + ·‖ C2: @ 16060 HT:17000 -> ▶ 16000 + ·‖ C2: @ 17060 HT:50764 -> ▶ 17000 + ++++ 8F: wake-up / shutdown + +‖▽▼▽‖ 5D: @ 17446 +‖▽▼▽‖ 6A: @ 17999 +‖▽▼▽‖ 98: @ 18212 +‖▽▼▽‖ CE: @ 18263 +‖▽▼▽‖ 74: @ 18327 +‖▽▼▽‖ D4: @ 18682 +‖▽▼▽‖ 70: @ 21125 +‖▽▼▽‖ C2: @ 50886 + diff --git a/doc/devel/dump/2023-12-09.Scheduler-Integration/SchedulerTestGraph.pdf b/doc/devel/dump/2023-12-09.Scheduler-Integration/SchedulerTestGraph.pdf new file mode 100644 index 000000000..04c93c9a3 Binary files /dev/null and b/doc/devel/dump/2023-12-09.Scheduler-Integration/SchedulerTestGraph.pdf differ diff --git a/doc/devel/dump/2023-12-09.Scheduler-Integration/index.txt b/doc/devel/dump/2023-12-09.Scheduler-Integration/index.txt index 43a041c9a..a62fe6c95 100644 --- a/doc/devel/dump/2023-12-09.Scheduler-Integration/index.txt +++ b/doc/devel/dump/2023-12-09.Scheduler-Integration/index.txt @@ -33,6 +33,8 @@ tangible CPU load and thus the job processing is absolutely dominated by the scheduler management overhead. Several workers, pulling concurrently, may create a slowdown due to contention on the »Grooming-Token« +SchedulerTestGraph.pdf:: + Visualisation of the computation structure used for these tests Dump-01:: example of a nice and clean run @@ -72,3 +74,9 @@ Dump-03:: appear in the log. This _may hint at additional contention generated by the dump output itself...._ +Dump-04:: + Example of a successful run with a computational load of 100µs per step. + This example was obtained form running `TestChainLoad_test::usageExample()` + with additional print-statements inserted into the code. + + diff --git a/tests/vault/gear/test-chain-load-test.cpp b/tests/vault/gear/test-chain-load-test.cpp index a24a67700..2514b75c4 100644 --- a/tests/vault/gear/test-chain-load-test.cpp +++ b/tests/vault/gear/test-chain-load-test.cpp @@ -27,6 +27,7 @@ #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" +#include "lib/test/diagnostic-output.hpp" #include "test-chain-load.hpp" #include "vault/gear/job.h" #include "lib/util.hpp" @@ -59,6 +60,10 @@ namespace test { /*****************************************************************//** * @test verify a tool to generate synthetic load for Scheduler tests. + * @remark statistics output and the generation of Graphviz-DOT diagrams + * is commented out; these diagnostics are crucial to understand + * the generated load pattern or to develop new graph shapes. + * Visualise graph with `dot -Tpng example.dot | display` * @see SchedulerService_test * @see SchedulerStress_test */ @@ -84,7 +89,8 @@ namespace test { /** @test demonstrate simple usage of the test-load - * @todo WIP 11/23 ✔ define ⟶ ✔ implement + * - build a graph with 64 nodes, grouped into small segments + * - use a scheduler instance to »perform« this graph */ void usageExample() @@ -94,22 +100,24 @@ namespace test { .configureShape_short_segments3_interleaved() .buildToplolgy(); + // while building the graph, node hashes are computed + CHECK (testLoad.getHash() == 0xD2F292D864CF8086); + + BlockFlowAlloc bFlow; EngineObserver watch; Scheduler scheduler{bFlow, watch}; - CHECK (testLoad.getHash() == 0xD2F292D864CF8086); - testLoad.setupSchedule(scheduler) .launch_and_wait(); + // invocation through Scheduler has reproduced all node hashes CHECK (testLoad.getHash() == 0xD2F292D864CF8086); } /** @test data structure to represent a computation Node - * @todo WIP 11/23 ✔ define ⟶ ✔ implement */ void verify_Node() @@ -195,7 +203,6 @@ namespace test { * - in the default case, nodes are linearly chained * - hash is also computed by chaining with predecessor hash * - hash computations can be reproduced - * @todo WIP 11/23 ✔ define ⟶ ✔ implement */ void verify_Topology() @@ -256,7 +263,6 @@ namespace test { * - with additional shuffling, the decisions are more random * - statistics can be computed to characterise the graph * - the graph can be visualised as _Graphviz diagram_ - * @todo WIP 11/23 ✔ define ⟶ ✔ implement */ void showcase_Expansion() @@ -326,7 +332,6 @@ namespace test { * all chains to be joined eventually * - expansion and reduction can counterbalance each other, * leading to localised »packages« of branchings and reductions - * @todo WIP 11/23 ✔ define ⟶ ✔ implement */ void showcase_Reduction() @@ -396,7 +401,6 @@ namespace test { * - the seed rule allows to start new chains in the middle of the graph * - combined with with reduction, the emerging structure resembles * the processing pattern encountered with real media calculations - * @todo WIP 11/23 ✔ define ⟶ ✔ implement */ void showcase_SeedChains() @@ -454,7 +458,6 @@ namespace test { * - this can lead to fragmentation into several sub-graphs * - these can be completely segregated, or appear interwoven * - equilibrium of seeding and pruning can be established - * @todo WIP 11/23 ✔ define ⟶ ✔ implement */ void showcase_PruneChains() @@ -595,7 +598,6 @@ namespace test { * parameter variations leading into repeated re-establishment * of some node constellation. When this is achieved, additional * shuffling can be introduced to uncover further potential. - * @todo WIP 11/23 ✔ define ⟶ ✔ implement */ void showcase_StablePattern() @@ -853,7 +855,6 @@ namespace test { /** @test verify calibration of a configurable computational load. - * @todo WIP 12/23 ✔ define ⟶ ✔ implement */ void verify_computation_load() @@ -921,7 +922,6 @@ namespace test { * that the last node is an exit node. The following code traverses * all nodes grouped into 4-node clusters to verify this regular * pattern and the calculated hashes. - * @todo WIP 11/23 ✔ define ⟶ ✔ implement */ void verify_reseed_recalculate() @@ -1024,13 +1024,62 @@ namespace test { - /** @test TODO compute synchronous execution time for reference - * @todo WIP 12/23 🔁 define ⟶ 🔁 implement + /** @test compute synchronous execution time for reference */ void verify_runtime_reference() { + double t1 = + TestChainLoad{64} + .configureShape_short_segments3_interleaved() + .buildToplolgy() + .calcRuntimeReference(); + double t2 = + TestChainLoad{64} + .configureShape_short_segments3_interleaved() + .buildToplolgy() + .calcRuntimeReference(1ms); + + double t3 = + TestChainLoad{256} + .configureShape_short_segments3_interleaved() + .buildToplolgy() + .calcRuntimeReference(); + + auto isWithin10Percent = [](double t, double r) + { + auto delta = abs (1.0 - t/r); + return delta < 0.1; + }; + + // the test-graph has 64 Nodes, + // each using the default load of 100µs + CHECK (isWithin10Percent(t1, 6400)); // thus overall we should be close to 6.4ms + CHECK (isWithin10Percent(t2, 10*t1)); // and the 10-fold load should yield 10-times + CHECK (isWithin10Percent(t3, 4*t1)); // using 4 times as much nodes (64->256) + + // the time measurement uses a performance + // which clears, re-seeds and calculates the complete graph + auto graph = + TestChainLoad{64} + .configureShape_short_segments3_interleaved() + .buildToplolgy(); + + CHECK (graph.getHash() == 0xD2F292D864CF8086); + + graph.clearNodeHashes(); + CHECK (graph.getHash() == 0); + + // this is used by the timing benchmark + graph.performGraphSynchronously(); + CHECK (graph.getHash() == 0xD2F292D864CF8086); + + graph.clearNodeHashes(); + CHECK (graph.getHash() == 0); + + graph.calcRuntimeReference(); + CHECK (graph.getHash() == 0xD2F292D864CF8086); } @@ -1045,7 +1094,6 @@ namespace test { * if all nodes are processed and all dependency connections * properly reported through the callback-λ, then calculating * this clone network should reproduce the original hash. - * @todo WIP 12/23 ✔ define ⟶ ✔ implement */ void verify_scheduling_setup() diff --git a/tests/vault/gear/test-chain-load.hpp b/tests/vault/gear/test-chain-load.hpp index 2df7508f8..04bd998e4 100644 --- a/tests/vault/gear/test-chain-load.hpp +++ b/tests/vault/gear/test-chain-load.hpp @@ -58,7 +58,7 @@ ** - reductionRule: controls joining of the graph into a combining successor node ** - seedingRule: controls injection of new start nodes in the middle of the graph ** - pruningRule: controls insertion of exit nodes to cut-off some chain immediately - ** - weightRule: controls assignment of a Node::weight to command the ComputationalLoad + ** - weightRule: controls assignment of a Node::weight to command the ComputationalLoad ** ** ## Usage ** A TestChainLoad instance is created with predetermined maximum fan factor and a fixed @@ -66,7 +66,7 @@ ** control functions can then be configured. The [topology generation](\ref TestChainLoad::buildTopology) ** then traverses the nodes, starting with the seed value from the root node, and establishes ** the complete node connectivity. After this priming, the expected result hash should be - ** [retrieved](\ref TestChainLoad::getHash). The node structure can than be traversed or + ** [retrieved](\ref TestChainLoad::getHash). The node structure can then be traversed or ** [scheduled as Render Jobs](\ref TestChainLoad::scheduleJobs). ** ** ## Observation tools @@ -75,6 +75,10 @@ ** and showing predecessor -> successor connectivity. Seed nodes are distinguished by ** circular shape. ** + ** The complete graph can be [performed synchronously](\ref TestChainLoad::performGraphSynchronously), + ** allowing to watch a [baseline run-time](\ref TestChainLoad::calcRuntimeReference) when execution + ** all nodes consecutively, using the configured load but without any time gaps. The run time + ** in µs can be compared to the timings observed when performing the graph through the Scheduler. ** Moreover, Statistics can be computed over the generated graph, allowing to draw some ** conclusions regarding node distribution and connectivity. ** @@ -157,6 +161,7 @@ namespace test { const auto SAFETY_TIMEOUT = 5s; ///< maximum time limit for test run, abort if exceeded const auto STANDARD_DEADLINE = 10ms; ///< deadline to use for each individual computation job const size_t DEFAULT_CHUNKSIZE = 64; ///< number of computation jobs to prepare in each planning round + const size_t GRAPH_BENCHMARK_RUNS = 5; ///< repetition count for reference calculation of a complete node graph const size_t LOAD_BENCHMARK_RUNS = 500; ///< repetition count for calibration benchmark for ComputationalLoad const double LOAD_SPEED_BASELINE = 100; ///< initial assumption for calculation speed (without calibration) const microseconds LOAD_DEFAULT_TIME = 100us; ///< default time delay produced by ComputationalLoad at `Node.weight==1` @@ -522,6 +527,11 @@ namespace test { { return rule(n); }; + auto calcNode = [&](Node* n) + { + n->calculate(); + n->weight = apply(weightRule_,n); + }; // visit all further nodes and establish links while (moreNodes()) @@ -533,8 +543,7 @@ namespace test { REQUIRE (spaceLeft()); for (Node* o : *curr) { // follow-up on all Nodes in current level... - o->calculate(); - o->weight = apply (weightRule_,o); + calcNode(o); if (apply (pruningRule_,o)) continue; // discontinue size_t toSeed = apply (seedingRule_, o); @@ -578,10 +587,10 @@ namespace test { node->level = level; for (Node* o : *next) { - o->calculate(); + calcNode(o); node->addPred(o); } - node->calculate(); + calcNode(node); // return move(*this); } @@ -689,6 +698,43 @@ namespace test { } + /** + * Conduct a number of benchmark runs over processing the Graph synchronously. + * @return runtime time in microseconds + * @remark can be used as reference point to judge Scheduler performance; + * - additional parallelisation could be exploited: ∅w / floor(∅w/concurrency) + * - but the Scheduler also adds overhead and dispatch leeway + */ + double + calcRuntimeReference(microseconds timeBase =LOAD_DEFAULT_TIME + ,size_t sizeBase =0 + ,size_t repeatCnt=GRAPH_BENCHMARK_RUNS + ) + { + return microBenchmark ([&]{ performGraphSynchronously(timeBase,sizeBase); } + ,repeatCnt) + .first; // ∅ runtime in µs + } + + /** Emulate complete graph processing in a single threaded loop. */ + TestChainLoad&& performGraphSynchronously(microseconds timeBase =LOAD_DEFAULT_TIME + ,size_t sizeBase =0); + + TestChainLoad&& + printRuntimeReference(microseconds timeBase =LOAD_DEFAULT_TIME + ,size_t sizeBase =0 + ,size_t repeatCnt=GRAPH_BENCHMARK_RUNS + ) + { + cout << _Fmt{"runtime ∅(%d) = %6.2fms (single-threaded)\n"} + % repeatCnt + % (1e-3 * calcRuntimeReference(timeBase,sizeBase,repeatCnt)) + << "───═══───═══───═══───═══───═══───═══───═══───═══───═══───═══───" + << endl; + return move(*this); + } + + Statistic computeGraphStatistics(); TestChainLoad&& printTopologyStatistics(); @@ -1119,6 +1165,7 @@ namespace test { * variable and can thus be reused. */ class ComputationalLoad + : util::MoveAssign { using Sink = volatile size_t; @@ -1245,6 +1292,42 @@ namespace test { }; + /** + * @param timeBase time delay produced by ComputationalLoad at `Node.weight==1`; + * can be set to zero to disable the synthetic processing load on nodes + * @param sizeBase allocation base size used; also causes switch to memory-access based load + * @see TestChainLoad::calcRuntimeReference() for a benchmark based on this processing + */ + template + TestChainLoad&& + TestChainLoad::performGraphSynchronously (microseconds timeBase, size_t sizeBase) + { + ComputationalLoad compuLoad; + compuLoad.timeBase = timeBase; + if (not sizeBase) + { + compuLoad.sizeBase = LOAD_DEFAULT_MEM_SIZE; + compuLoad.useAllocation =false; + } + else + { + compuLoad.sizeBase = sizeBase; + compuLoad.useAllocation =true; + } + compuLoad.maybeCalibrate(); + + size_t seed = this->getSeed(); + for (Node& n : allNodes()) + { + n.hash = isStart(n)? seed : 0; + if (n.weight) + compuLoad.invoke (n.weight); + n.calculate(); + } + return move(*this); + } + + @@ -1725,7 +1808,7 @@ cout<<"ANCHOR="+relT(ank)+" preRoll="+util::toString(_raw(_uTicks(preRoll_)))< typename TestChainLoad::ScheduleCtx - TestChainLoad::setupSchedule(Scheduler& scheduler) + TestChainLoad::setupSchedule (Scheduler& scheduler) { clearNodeHashes(); return ScheduleCtx{*this, scheduler}; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 80464cab0..a02383649 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -85308,9 +85308,33 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + + +

+ ...denn wir wissen grundsätzlich nie, wieviel Kapazität wir „in der Rückhand“ haben; nur falls sich das grundsätzlich ändert, könnte man über derartige Priorisierungen nachdenken. Das wäre durchaus möglich, würde aber mit dem Design-Prinzip dieses Schedulers brechen: daß nämlich die Worker aktiv sind und nebenbei die Administration mit erledigen, und daß Kapazität über mehrere Stufen „fließt“ +

+ +
+ +
+
+ + + + +

+ weil bei etwa 100µs die Granularität des OS-Schedulers liegt; man kann zwar deutlich kleinere Schlaf-Zeiten angeben und bekommt dann auch was Kürzeres und zwar im Schnitt. Aber im Einzelfall bekommt man dann eben doch x-mal wieder etwas über 100µs. Gemäß Zielabwägung habe ich daher die Grenze für spinning yield-wait auf 50µs gesetzt, denn wenn's mehr als 50µs sind, dann ist es auch schon egal wenn wir über 100µs bekommen +

+ +
+ +
@@ -93428,8 +93452,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -96083,7 +96107,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -96155,13 +96179,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + - + + + + @@ -96379,7 +96406,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -96393,9 +96420,6 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - @@ -96813,16 +96837,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + - + - + @@ -96843,8 +96867,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -99493,9 +99517,25 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + + + + + + + + + + + + + @@ -99677,6 +99717,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + @@ -99777,7 +99822,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- +
@@ -100952,9 +100997,49 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +

+ Dies müßte in eine Prüf-Klammer eingebunden werden, die den Original-Graphen zu fassen bekommt, bevor der Scheduler gestartet wird +

+
    +
  • + man müßte einen Vector aller Node-Hashes aufzeichnen — ist ein Einzeiler mit explore(allNodes)...effuse() +
  • +
  • + danach macht man das Gleiche und einen Vergleich in einem Pass ⟿ abweichende Nodes in geeigneter Datenstruktur markieren +
  • +
  • + zusätzlich bedarf es einer Erweiterung des generateTopologyDOT: ein zusätzliches Argument bringt mark-up per Node ein; der fließt dann in die Node-Generierung ein; konkret wäre das eine Farbmarkierung der fehlerhaften Nodes +
  • +
+ +
- - + + + + +
    +
  • + will man überhaupt im Einzelnen wissen, wo der Hash abgewichen ist? +
  • +
  • + was kann man mit dieser Information anfangen, ohne einen kompletten Berechnungs-Trail genau dieses Laufes zu haben? +
  • +
+ +
+ +
+
+
+ + @@ -101059,20 +101144,48 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -102663,6 +102776,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + +