-
Notifications
You must be signed in to change notification settings - Fork 118
Improve parallelism by solving most difficult deals first #216
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
base: develop
Are you sure you want to change the base?
Changes from 5 commits
2182b0f
8ecebc8
6234595
b08925f
2d57e8d
f4ed912
f733867
fa2c84c
07a33cd
5e34528
6ead0ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,12 +8,15 @@ | |
| */ | ||
|
|
||
| #include "calc_tables.hpp" | ||
| #include <algorithm> | ||
| #include <numeric> | ||
| #include <vector> | ||
|
|
||
| #include <pbn.hpp> | ||
| #include <solve_board.hpp> | ||
| #include <api/solve_board.hpp> | ||
| #include <solver_if.hpp> | ||
| #include <lookup_tables/lookup_tables.hpp> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I should probably pull and compile, but I don't see what's being used from this header. fanout comes from scheduler.hpp and all the other called functions appear to be in std:: namespace. What did I miss? |
||
| #include <system/memory.hpp> | ||
| #include <system/parallel_boards.hpp> | ||
| #include <system/scheduler.hpp> | ||
|
|
@@ -23,11 +26,41 @@ | |
| extern Memory memory; | ||
| extern Scheduler scheduler; | ||
|
|
||
|
tameware marked this conversation as resolved.
|
||
| // Legacy overload (creates temporary context) | ||
| namespace | ||
| { | ||
| // Cheap structural difficulty estimate (cards only, trump-independent). Used to | ||
| // dispatch the hardest boards first so the parallel tail is short. Mirrors | ||
| // Scheduler::Fanout: per hand, sum the number of card groups per suit, with a | ||
| // bonus for voids. | ||
| auto deal_fanout(const Deal& dl) -> int | ||
| { | ||
| int fanout = 0; | ||
| for (int h = 0; h < DDS_HANDS; h++) | ||
| { | ||
| int fanout_suit = 0; | ||
| int num_voids = 0; | ||
| for (int s = 0; s < DDS_SUITS; s++) | ||
| { | ||
| const int c = static_cast<int>(dl.remainCards[h][s] >> 2); | ||
| fanout_suit += group_data[c].last_group_ + 1; | ||
| if (c == 0) | ||
| num_voids++; | ||
| } | ||
| fanout_suit += num_voids * fanout_suit; | ||
| fanout += fanout_suit; | ||
| } | ||
| return fanout; | ||
| } | ||
| } | ||
|
tameware marked this conversation as resolved.
Outdated
|
||
|
|
||
| // Legacy overload (creates temporary context). difficulty_sort dispatches the | ||
| // hardest boards first; it only helps across distinct deals (batch calc), so it | ||
| // is skipped for a single deal (all boards share one deal / one fanout). | ||
| auto calc_all_boards_n( | ||
| Boards * bop, | ||
| SolvedBoards * solvedp, | ||
| int max_threads = 0) -> int; | ||
| int max_threads = 0, | ||
| bool difficulty_sort = true) -> int; | ||
|
|
||
|
|
||
| auto calc_single_common_internal( | ||
|
|
@@ -110,7 +143,8 @@ auto calc_all_boards_n( | |
| auto calc_all_boards_n( | ||
| Boards * bop, | ||
| SolvedBoards * solvedp, | ||
| int max_threads) -> int | ||
| int max_threads, | ||
| bool difficulty_sort) -> int | ||
| { | ||
| const int n = bop->no_of_boards; | ||
| if (n > MAXNOOFBOARDS) | ||
|
|
@@ -137,11 +171,30 @@ auto calc_all_boards_n( | |
| else | ||
| { | ||
| std::vector<SolverContext> contexts(static_cast<unsigned>(nthreads)); | ||
|
|
||
| // Dispatch hardest boards first to shorten the parallel tail. This only | ||
| // helps across distinct deals (batch calc); for a single deal every board | ||
| // shares one fanout, so the sort is skipped (it would be a no-op anyway). | ||
| std::vector<int> order; | ||
| if (difficulty_sort) | ||
| { | ||
| std::vector<int> fanout(static_cast<unsigned>(n)); | ||
| for (int i = 0; i < n; i++) | ||
| fanout[static_cast<unsigned>(i)] = deal_fanout(bop->deals[i]); | ||
| order.resize(static_cast<unsigned>(n)); | ||
| std::iota(order.begin(), order.end(), 0); | ||
| std::stable_sort(order.begin(), order.end(), | ||
| [&](const int a, const int b) { | ||
| return fanout[static_cast<unsigned>(a)] > fanout[static_cast<unsigned>(b)]; | ||
| }); | ||
| } | ||
|
|
||
| err = parallel_all_boards_n(n, nthreads, | ||
| [&](const int worker_id, const int bno) -> int { | ||
| return calc_single_common_internal( | ||
| contexts[static_cast<unsigned>(worker_id)], *bop, *solvedp, bno); | ||
| }); | ||
| }, | ||
| order.empty() ? nullptr : &order); | ||
| } | ||
|
|
||
| END_BLOCK_TIMER; | ||
|
|
@@ -192,7 +245,8 @@ int STDCALL CalcDDtableN( | |
| ind++; | ||
| } | ||
|
|
||
| int res = calc_all_boards_n(&bo, &solved, maxThreads); | ||
| // Single deal: all boards share one deal, so hardest-first sorting is a no-op. | ||
| int res = calc_all_boards_n(&bo, &solved, maxThreads, /*difficulty_sort=*/false); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trivial Inline variable-name comment isn't necessary. |
||
| if (res != 1) | ||
| return res; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well fix the indenting problem at the same time.