@@ -65,21 +65,30 @@ int main() {
6565
6666 {
6767 server_adaptive_dm_state explore;
68- assert (explore.profit_explore_depth_for_step (15 , 15 , 1 ) == 1 );
69- assert (explore.profit_explore_depth_for_step (15 , 15 , 2 ) == 2 );
70- assert (explore.profit_explore_depth_for_step (15 , 15 , 3 ) == 3 );
71- assert (explore.profit_explore_depth_for_step (15 , 15 , 4 ) == 4 );
72- assert (explore.profit_explore_depth_for_step (15 , 15 , 14 ) == 14 );
73- assert (explore.profit_explore_depth_for_step (15 , 15 , 15 ) == 1 );
74- assert (explore.profit_explore_depth_for_step (8 , 15 , 1 ) == 9 );
75- assert (explore.profit_explore_depth_for_step (8 , 15 , 7 ) == 15 );
76- assert (explore.profit_explore_depth_for_step (8 , 15 , 8 ) == 1 );
68+ assert (explore.profit_explore_depth_for_step (15 , 15 , 1 ) == 14 );
69+ assert (explore.profit_explore_depth_for_step (15 , 15 , 2 ) == 13 );
70+ assert (explore.profit_explore_depth_for_step (15 , 15 , 3 ) == 12 );
71+ assert (explore.profit_explore_depth_for_step (15 , 15 , 4 ) == 11 );
72+ assert (explore.profit_explore_depth_for_step (15 , 15 , 5 ) == 10 );
73+ assert (explore.profit_explore_depth_for_step (15 , 15 , 8 ) == 14 );
74+ assert (explore.profit_explore_depth_for_step (8 , 15 , 1 ) == 7 );
75+ assert (explore.profit_explore_depth_for_step (8 , 15 , 2 ) == 9 );
76+ assert (explore.profit_explore_depth_for_step (8 , 15 , 7 ) == 4 );
77+
78+ int active_order[SERVER_ADAPTIVE_DM_PROFIT_CANDIDATES ];
79+ const int n_active = explore.profit_active_explore_depths (
80+ 15 , 15 , active_order, SERVER_ADAPTIVE_DM_PROFIT_CANDIDATES );
81+ assert (n_active > 0 );
82+ assert (n_active <= 7 );
83+ for (int i = 0 ; i < n_active; ++i) {
84+ assert (active_order[i] >= 4 );
85+ }
7786 }
7887
7988 {
8089 server_adaptive_dm_state explore_ready;
8190 explore_ready.dm_profit_min_samples = 1 ;
82- assert (explore_ready.profit_next_unready_explore_depth (10 , 15 , 1 ) == 11 );
91+ assert (explore_ready.profit_next_unready_explore_depth (10 , 15 , 1 ) == 9 );
8392 const int ready_depths[] = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ,
8493 9 , 10 , 11 , 12 , 13 , 14 , 15 };
8594 for (const int depth : ready_depths) {
@@ -90,6 +99,45 @@ int main() {
9099 assert (explore_ready.profit_next_unready_explore_depth (10 , 15 , 1 ) == 0 );
91100 }
92101
102+ {
103+ server_adaptive_dm_state strong_max;
104+ strong_max.dm_profit_min_samples = 1 ;
105+ strong_max.adaptive_n_max = 15 ;
106+ strong_max.profit_last_recommended_n = 15 ;
107+
108+ strong_max.observe_profit_timing (0 , 0 , 0 , 0 .0f , 30 .0f , 0 .0f , 30 .0f );
109+ for (int i = 0 ; i < 6 ; ++i) {
110+ observe_profit_cycle (strong_max, 15 , 15 , 10 , 60 .0f );
111+ }
112+ assert (strong_max.profit_next_unready_explore_depth (15 , 15 , 1 ) == 0 );
113+ }
114+
115+ {
116+ server_adaptive_dm_state weak_max;
117+ weak_max.dm_profit_min_samples = 1 ;
118+ weak_max.adaptive_n_max = 15 ;
119+ weak_max.profit_last_recommended_n = 15 ;
120+
121+ weak_max.observe_profit_timing (0 , 0 , 0 , 0 .0f , 30 .0f , 0 .0f , 30 .0f );
122+ for (int i = 0 ; i < 6 ; ++i) {
123+ observe_profit_cycle (weak_max, 15 , 15 , 1 , 95 .0f );
124+ }
125+ assert (weak_max.profit_next_unready_explore_depth (15 , 15 , 1 ) == 14 );
126+ }
127+
128+ {
129+ server_adaptive_dm_state strong_mid;
130+ strong_mid.dm_profit_min_samples = 1 ;
131+ strong_mid.adaptive_n_max = 8 ;
132+ strong_mid.profit_last_recommended_n = 8 ;
133+
134+ strong_mid.observe_profit_timing (0 , 0 , 0 , 0 .0f , 30 .0f , 0 .0f , 30 .0f );
135+ for (int i = 0 ; i < 6 ; ++i) {
136+ observe_profit_cycle (strong_mid, 8 , 8 , 7 , 50 .0f );
137+ }
138+ assert (strong_mid.profit_next_unready_explore_depth (8 , 15 , 1 ) == 9 );
139+ }
140+
93141 {
94142 server_adaptive_dm_state initial_large;
95143 initial_large.dm_profit_min_samples = 1 ;
@@ -761,9 +809,39 @@ int main() {
761809
762810 assert (preserved_challenger.decide_profit_n_max (15 ) == 15 );
763811 observe_profit_cycle (preserved_challenger, 12 , 12 , 10 , 70 .0f );
812+ assert (preserved_challenger.decide_profit_n_max (15 ) == 15 );
813+ for (int i = 0 ; i < 5 ; ++i) {
814+ observe_profit_cycle (preserved_challenger, 12 , 12 , 10 , 70 .0f );
815+ }
764816 assert (preserved_challenger.decide_profit_n_max (15 ) == 13 );
765817 }
766818
819+ // A preserved max-depth run must actively collect fresh local challenger
820+ // evidence. Stale global stats can rank a lower challenger, but they cannot
821+ // replace a same-request probe, and active mode should not sweep the low end.
822+ {
823+ server_adaptive_dm_state preserved_probe;
824+ preserved_probe.dm_profit_min_samples = 1 ;
825+ preserved_probe.adaptive_n_max = 15 ;
826+ preserved_probe.profit_last_recommended_n = 15 ;
827+ preserved_probe.profit_has_key = true ;
828+ preserved_probe.profit_key = {};
829+ preserved_probe.profit_key .base_n_max = 15 ;
830+
831+ preserved_probe.observe_profit_timing (0 , 0 , 0 , 0 .0f , 30 .0f , 0 .0f , 30 .0f );
832+ observe_profit_cycle (preserved_probe, 12 , 12 , 10 , 70 .0f );
833+ observe_profit_cycle (preserved_probe, 15 , 15 , 10 , 90 .0f );
834+
835+ preserved_probe.reset_request_state (true );
836+ assert (preserved_probe.profit_next_unready_explore_depth (15 , 15 , 1 ) == 14 );
837+ observe_profit_cycle (preserved_probe, 14 , 14 , 10 , 70 .0f );
838+ assert (preserved_probe.profit_next_unready_explore_depth (15 , 15 , 1 ) == 14 );
839+ for (int i = 0 ; i < 5 ; ++i) {
840+ observe_profit_cycle (preserved_probe, 14 , 14 , 10 , 70 .0f );
841+ }
842+ assert (preserved_probe.profit_next_unready_explore_depth (15 , 15 , 1 ) == 13 );
843+ }
844+
767845 // test lower acceptance can still be faster; controller must optimize TPS,
768846 // not raw acceptance rate.
769847 {
@@ -988,34 +1066,37 @@ int main() {
9881066 assert (recent_acceptance.decide_profit_n_max (15 ) == 10 );
9891067 }
9901068
991- // Off-state probes must sweep through every low-end depth before backing
992- // off, so a marginal prompt can still discover depth 1/2/3 instead of
993- // treating depth 4 as the minimum viable speculative horizon.
1069+ // Off-state probes should try useful anchors first, then fill nearby low
1070+ // depths. Dense candidate scoring is separate; recovery probes should not
1071+ // spend an entire sweep walking 1,2,3,... before testing the known productive
1072+ // mid/high range.
9941073 {
9951074 server_adaptive_dm_state sweep;
9961075 sweep.dm_profit_min_samples = 1 ;
9971076 sweep.dm_probe_interval = 4 ;
9981077 sweep.adaptive_n_max = 0 ;
9991078 sweep.observe_profit_timing (0 , 0 , 0 , 0 .0f , 30 .0f , 0 .0f , 30 .0f );
10001079
1001- assert (sweep.profit_next_off_probe_depth (15 , 3 ) == 1 );
1002- for (int depth = 1 ; depth <= 14 ; ++depth) {
1080+ const int expected_order[] = {4 , 8 , 12 , 15 , 2 , 3 , 1 , 5 , 7 , 9 , 11 , 13 , 14 , 6 , 10 };
1081+ for (int i = 0 ; i < 14 ; ++i) {
1082+ const int depth = expected_order[i];
1083+ assert (sweep.profit_next_off_probe_depth (15 , 3 ) == depth);
10031084 observe_profit_cycle (sweep, depth, depth, 0 , 60 .0f + (float ) depth);
10041085 sweep.profit_note_off_probe_result (depth, 15 , false );
1005- assert (sweep.profit_next_off_probe_depth (15 , 3 ) == depth + 1 );
1086+ assert (sweep.profit_next_off_probe_depth (15 , 3 ) == expected_order[i + 1 ] );
10061087 assert (sweep.profit_off_probe_failures == 0 );
10071088 assert (sweep.profit_off_probe_interval () == 4 );
10081089 }
10091090
1010- observe_profit_cycle (sweep, 15 , 15 , 0 , 80 .0f );
1011- sweep.profit_note_off_probe_result (15 , 15 , false );
1012- assert (sweep.profit_next_off_probe_depth (15 , 3 ) == 1 );
1091+ observe_profit_cycle (sweep, expected_order[ 14 ], expected_order[ 14 ] , 0 , 80 .0f );
1092+ sweep.profit_note_off_probe_result (expected_order[ 14 ] , 15 , false );
1093+ assert (sweep.profit_next_off_probe_depth (15 , 3 ) == expected_order[ 0 ] );
10131094 assert (sweep.profit_off_probe_failures == 1 );
10141095 assert (sweep.profit_off_probe_interval () == 8 );
10151096
1016- sweep.profit_note_off_probe_result (1 , 15 , true );
1097+ sweep.profit_note_off_probe_result (expected_order[ 0 ] , 15 , true );
10171098 assert (sweep.profit_off_probe_failures == 0 );
1018- assert (sweep.profit_next_off_probe_depth (15 , 3 ) == 1 );
1099+ assert (sweep.profit_next_off_probe_depth (15 , 3 ) == expected_order[ 0 ] );
10191100 }
10201101
10211102 // Failed wake probes advance the off-state sweep instead of retrying the
@@ -1034,7 +1115,7 @@ int main() {
10341115 assert (failed.profit_off_probe_interval () == 4 );
10351116 assert (failed.decide_profit_n_max (8 ) == 0 );
10361117 assert (failed.profit_off_probe_failures == 0 );
1037- assert (failed.profit_next_off_probe_depth (8 , 2 ) == 5 );
1118+ assert (failed.profit_next_off_probe_depth (8 , 2 ) == 8 );
10381119 assert (failed.profit_off_probe_interval () == 4 );
10391120 }
10401121
0 commit comments