@@ -34,8 +34,7 @@ struct PctStrategy : public BaseStrategyWithThreads<TargetObj, Verifier> {
3434 size_t NextThreadId () override {
3535 auto & threads = this ->threads ;
3636 int max = std::numeric_limits<int >::min ();
37- int snd_max = std::numeric_limits<int >::min ();
38- size_t index_of_max = 0 , index_of_snd_max = 0 ;
37+ size_t index_of_max = 0 ;
3938 // Have to ignore waiting threads, so can't do it faster than O(n)
4039 for (size_t i = 0 ; i < threads.size (); ++i) {
4140 // Ignore waiting tasks
@@ -51,21 +50,31 @@ struct PctStrategy : public BaseStrategyWithThreads<TargetObj, Verifier> {
5150 }
5251
5352 if (max <= priorities[i]) {
54- index_of_snd_max = index_of_max;
55- snd_max = max;
5653 max = priorities[i];
5754 index_of_max = i;
58- } else if (snd_max <= priorities[i]) {
59- snd_max = priorities[i];
60- index_of_snd_max = i;
55+ }
56+ }
57+
58+ if (round_robin_stage > 0 ) {
59+ for (size_t attempt = 0 ; attempt < threads.size (); ++attempt) {
60+ auto i = (++last_chosen) % threads.size ();
61+ if (!threads[i].empty () && threads[i].back ()->IsBlocked ()) {
62+ continue ;
63+ }
64+ index_of_max = i;
65+ max = priorities[i];
66+ break ;
67+ }
68+ // debug(stderr, "round robin choose: %d\n", index_of_max);
69+ if (round_robin_start == index_of_max) {
70+ --round_robin_stage;
6171 }
6272 }
6373
6474 // TODO: Choose wiser constant
65- if (count_chosen_same == 100 && index_of_max == last_chosen &&
66- snd_max != std::numeric_limits<int >::min ()) {
67- priorities[index_of_max] = snd_max - 1 ;
68- index_of_max = index_of_snd_max;
75+ if (count_chosen_same == 1000 && index_of_max == last_chosen) {
76+ round_robin_stage = 5 ;
77+ round_robin_start = index_of_max;
6978 }
7079
7180 if (index_of_max == last_chosen) {
@@ -97,8 +106,7 @@ struct PctStrategy : public BaseStrategyWithThreads<TargetObj, Verifier> {
97106 auto & round_schedule = this ->round_schedule ;
98107 auto & threads = this ->threads ;
99108 int max = std::numeric_limits<int >::min ();
100- int snd_max = std::numeric_limits<int >::min ();
101- size_t index_of_max = 0 , index_of_snd_max = 0 ;
109+ size_t index_of_max = 0 ;
102110 // Have to ignore waiting threads, so can't do it faster than O(n)
103111 for (size_t i = 0 ; i < threads.size (); ++i) {
104112 int task_index = this ->GetNextTaskInThread (i);
@@ -113,29 +121,40 @@ struct PctStrategy : public BaseStrategyWithThreads<TargetObj, Verifier> {
113121 }
114122
115123 if (max <= priorities[i]) {
116- index_of_snd_max = index_of_max;
117- snd_max = max;
118124 max = priorities[i];
119125 index_of_max = i;
120- } else if (snd_max <= priorities[i]) {
121- snd_max = priorities[i];
122- index_of_snd_max = i;
126+ }
127+ }
128+
129+ if (round_robin_stage > 0 ) {
130+ for (size_t attempt = 0 ; attempt < threads.size (); ++attempt) {
131+ auto i = (++last_chosen) % threads.size ();
132+ int task_index = this ->GetNextTaskInThread (i);
133+ if (task_index == threads[i].size () ||
134+ threads[i][task_index]->IsBlocked ()) {
135+ continue ;
136+ }
137+ index_of_max = i;
138+ max = priorities[i];
139+ break ;
140+ }
141+ // debug(stderr, "round robin choose: %d\n", index_of_max);
142+ if (round_robin_start == index_of_max) {
143+ --round_robin_stage;
123144 }
124145 }
125146
126147 // TODO: Choose wiser constant
127- if (count_chosen_same == 100 && index_of_max == last_chosen &&
128- snd_max != std::numeric_limits<int >::min ()) {
129- priorities[index_of_max] = snd_max - 1 ;
130- index_of_max = index_of_snd_max;
148+ if (count_chosen_same == 1000 && index_of_max == last_chosen) {
149+ round_robin_stage = 5 ;
150+ round_robin_start = index_of_max;
131151 }
132152
133153 if (index_of_max == last_chosen) {
134154 ++count_chosen_same;
135155 } else {
136156 count_chosen_same = 1 ;
137157 }
138-
139158 last_chosen = index_of_max;
140159 // Picked thread is `index_of_max`
141160 int next_task_index = this ->GetNextTaskInThread (index_of_max);
@@ -179,6 +198,7 @@ struct PctStrategy : public BaseStrategyWithThreads<TargetObj, Verifier> {
179198 k_statistics.push_back (current_schedule_length);
180199 current_schedule_length = 0 ;
181200 count_chosen_same = 0 ;
201+ round_robin_stage = 0 ;
182202
183203 // current_depth have been increased
184204 size_t new_k = std::reduce (k_statistics.begin (), k_statistics.end ()) /
@@ -211,6 +231,8 @@ struct PctStrategy : public BaseStrategyWithThreads<TargetObj, Verifier> {
211231 // original article)
212232 size_t count_chosen_same;
213233 size_t last_chosen;
234+ size_t round_robin_start;
235+ size_t round_robin_stage{0 };
214236 std::vector<int > priorities;
215237 std::vector<size_t > priority_change_points;
216238 std::mt19937 rng;
0 commit comments