Skip to content

Commit 71d1272

Browse files
committed
replaced locks with atomics
1 parent 27ee927 commit 71d1272

File tree

5 files changed

+9
-33
lines changed

5 files changed

+9
-33
lines changed

cpp/src/dual_simplex/bnb_worker.hpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,11 @@ class bnb_worker_pool_t {
179179
}
180180
}
181181

182+
// Here, we are assuming that the master is the only
183+
// thread that can retrieve/pop an idle worker.
182184
bnb_worker_data_t<i_t, f_t>* get_idle_worker()
183185
{
184186
std::lock_guard<omp_mutex_t> lock(mutex_);
185-
186187
if (idle_workers_.empty()) {
187188
return nullptr;
188189
} else {
@@ -191,6 +192,8 @@ class bnb_worker_pool_t {
191192
}
192193
}
193194

195+
// Here, we are assuming that the master is the only
196+
// thread that can retrieve/pop an idle worker.
194197
void pop_idle_worker()
195198
{
196199
std::lock_guard<omp_mutex_t> lock(mutex_);
@@ -200,20 +203,6 @@ class bnb_worker_pool_t {
200203
}
201204
}
202205

203-
bnb_worker_data_t<i_t, f_t>* get_and_pop_idle_worker()
204-
{
205-
std::lock_guard<omp_mutex_t> lock(mutex_);
206-
207-
if (idle_workers_.empty()) {
208-
return nullptr;
209-
} else {
210-
i_t idx = idle_workers_.front();
211-
idle_workers_.pop_front();
212-
num_idle_workers_--;
213-
return workers_[idx].get();
214-
}
215-
}
216-
217206
void return_worker_to_pool(bnb_worker_data_t<i_t, f_t>* worker)
218207
{
219208
worker->is_active = false;

cpp/src/dual_simplex/branch_and_bound.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ void branch_and_bound_t<i_t, f_t>::report(char symbol, f_t obj, f_t lower_bound,
282282
i_t nodes_unexplored = exploration_stats_.nodes_unexplored;
283283
f_t user_obj = compute_user_objective(original_lp_, obj);
284284
f_t user_lower = compute_user_objective(original_lp_, lower_bound);
285-
f_t iter_node = (f_t)exploration_stats_.total_lp_iters / nodes_explored;
285+
f_t iter_node = nodes_explored > 0 ? (f_t)exploration_stats_.total_lp_iters / nodes_explored : 0;
286286
std::string user_gap = user_mip_gap<f_t>(user_obj, user_lower);
287287
settings_.log.printf("%c %10d %10lu %+13.6e %+10.6e %6d %7.1e %s %9.2f\n",
288288
symbol,

cpp/src/dual_simplex/diving_heuristics.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,12 @@ branch_variable_t<i_t> pseudocost_diving(pseudo_costs_t<i_t, f_t>& pc,
8888
f_t f_down = solution[j] - std::floor(solution[j]);
8989
f_t f_up = std::ceil(solution[j]) - solution[j];
9090

91-
pc.pseudo_cost_mutex[j].lock();
9291
f_t pc_down = pc.pseudo_cost_num_down[j] != 0
9392
? pc.pseudo_cost_sum_down[j] / pc.pseudo_cost_num_down[j]
9493
: pseudo_cost_down_avg;
9594

9695
f_t pc_up = pc.pseudo_cost_num_up[j] != 0 ? pc.pseudo_cost_sum_up[j] / pc.pseudo_cost_num_up[j]
9796
: pseudo_cost_up_avg;
98-
pc.pseudo_cost_mutex[j].unlock();
9997

10098
f_t score_down = std::sqrt(f_up) * (1 + pc_up) / (1 + pc_down);
10199
f_t score_up = std::sqrt(f_down) * (1 + pc_down) / (1 + pc_up);
@@ -167,14 +165,12 @@ branch_variable_t<i_t> guided_diving(pseudo_costs_t<i_t, f_t>& pc,
167165
rounding_direction_t dir =
168166
down_dist < up_dist + eps ? rounding_direction_t::DOWN : rounding_direction_t::UP;
169167

170-
pc.pseudo_cost_mutex[j].lock();
171168
f_t pc_down = pc.pseudo_cost_num_down[j] != 0
172169
? pc.pseudo_cost_sum_down[j] / pc.pseudo_cost_num_down[j]
173170
: pseudo_cost_down_avg;
174171

175172
f_t pc_up = pc.pseudo_cost_num_up[j] != 0 ? pc.pseudo_cost_sum_up[j] / pc.pseudo_cost_num_up[j]
176173
: pseudo_cost_up_avg;
177-
pc.pseudo_cost_mutex[j].unlock();
178174

179175
f_t score1 = dir == rounding_direction_t::DOWN ? 5 * pc_down * f_down : 5 * pc_up * f_up;
180176
f_t score2 = dir == rounding_direction_t::DOWN ? pc_up * f_up : pc_down * f_down;

cpp/src/dual_simplex/pseudo_costs.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ template <typename i_t, typename f_t>
270270
void pseudo_costs_t<i_t, f_t>::update_pseudo_costs(mip_node_t<i_t, f_t>* node_ptr,
271271
f_t leaf_objective)
272272
{
273-
std::lock_guard<omp_mutex_t> lock(pseudo_cost_mutex[node_ptr->branch_var]);
274273
const f_t change_in_obj = leaf_objective - node_ptr->lower_bound;
275274
const f_t frac = node_ptr->branch_dir == rounding_direction_t::DOWN
276275
? node_ptr->fractional_val - std::floor(node_ptr->fractional_val)
@@ -296,8 +295,6 @@ void pseudo_costs_t<i_t, f_t>::initialized(i_t& num_initialized_down,
296295
pseudo_cost_up_avg = 0;
297296
const i_t n = pseudo_cost_sum_down.size();
298297
for (i_t j = 0; j < n; j++) {
299-
std::lock_guard<omp_mutex_t> lock(pseudo_cost_mutex[j]);
300-
301298
if (pseudo_cost_num_down[j] > 0) {
302299
num_initialized_down++;
303300
if (std::isfinite(pseudo_cost_sum_down[j])) {
@@ -351,7 +348,6 @@ i_t pseudo_costs_t<i_t, f_t>::variable_selection(const std::vector<i_t>& fractio
351348
for (i_t k = 0; k < num_fractional; k++) {
352349
const i_t j = fractional[k];
353350

354-
pseudo_cost_mutex[j].lock();
355351
if (pseudo_cost_num_down[j] != 0) {
356352
pseudo_cost_down[k] = pseudo_cost_sum_down[j] / pseudo_cost_num_down[j];
357353
} else {
@@ -363,7 +359,6 @@ i_t pseudo_costs_t<i_t, f_t>::variable_selection(const std::vector<i_t>& fractio
363359
} else {
364360
pseudo_cost_up[k] = pseudo_cost_up_avg;
365361
}
366-
pseudo_cost_mutex[j].unlock();
367362

368363
constexpr f_t eps = 1e-6;
369364
const f_t f_down = solution[j] - std::floor(solution[j]);
@@ -444,8 +439,6 @@ i_t pseudo_costs_t<i_t, f_t>::reliable_variable_selection(
444439
omp_mutex_t score_mutex;
445440

446441
for (auto j : fractional) {
447-
std::lock_guard<omp_mutex_t> lock(pseudo_cost_mutex[j]);
448-
449442
if (pseudo_cost_num_down[j] < reliable_threshold ||
450443
pseudo_cost_num_up[j] < reliable_threshold) {
451444
unreliable_list.push_back(j);
@@ -599,7 +592,6 @@ f_t pseudo_costs_t<i_t, f_t>::obj_estimate(const std::vector<i_t>& fractional,
599592
f_t pseudo_cost_down = 0;
600593
f_t pseudo_cost_up = 0;
601594

602-
pseudo_cost_mutex[j].lock();
603595
if (pseudo_cost_num_down[j] != 0) {
604596
pseudo_cost_down = pseudo_cost_sum_down[j] / pseudo_cost_num_down[j];
605597
} else {
@@ -611,7 +603,6 @@ f_t pseudo_costs_t<i_t, f_t>::obj_estimate(const std::vector<i_t>& fractional,
611603
} else {
612604
pseudo_cost_up = pseudo_cost_up_avg;
613605
}
614-
pseudo_cost_mutex[j].unlock();
615606

616607
constexpr f_t eps = 1e-6;
617608
const f_t f_down = solution[j] - std::floor(solution[j]);

cpp/src/dual_simplex/pseudo_costs.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ class pseudo_costs_t {
6969

7070
void update_pseudo_costs_from_strong_branching(const std::vector<i_t>& fractional,
7171
const std::vector<f_t>& root_soln);
72-
std::vector<f_t> pseudo_cost_sum_up;
73-
std::vector<f_t> pseudo_cost_sum_down;
74-
std::vector<i_t> pseudo_cost_num_up;
75-
std::vector<i_t> pseudo_cost_num_down;
72+
std::vector<omp_atomic_t<f_t>> pseudo_cost_sum_up;
73+
std::vector<omp_atomic_t<f_t>> pseudo_cost_sum_down;
74+
std::vector<omp_atomic_t<i_t>> pseudo_cost_num_up;
75+
std::vector<omp_atomic_t<i_t>> pseudo_cost_num_down;
7676
std::vector<f_t> strong_branch_down;
7777
std::vector<f_t> strong_branch_up;
7878
std::vector<omp_mutex_t> pseudo_cost_mutex;

0 commit comments

Comments
 (0)