Multithread DENSE_SCHUR

Replace the global lock in BlockRandomAccessDenseMatrix
with a per cell lock.

Change-Id: Iddbe38616157b6e0d3770eede3335a056c3ba18c
This commit is contained in:
Sameer Agarwal
2013-03-03 18:06:00 -08:00
parent 31730ef55d
commit a363a7b69c
4 changed files with 12 additions and 21 deletions
@@ -40,16 +40,21 @@ namespace internal {
BlockRandomAccessDenseMatrix::BlockRandomAccessDenseMatrix(
const vector<int>& blocks) {
block_layout_.resize(blocks.size(), 0);
const int num_blocks = blocks.size();
block_layout_.resize(num_blocks, 0);
num_rows_ = 0;
for (int i = 0; i < blocks.size(); ++i) {
for (int i = 0; i < num_blocks; ++i) {
block_layout_[i] = num_rows_;
num_rows_ += blocks[i];
}
values_.reset(new double[num_rows_ * num_rows_]);
CHECK_NOTNULL(values_.get());
cell_info_.values = values_.get();
cell_infos_.reset(new CellInfo[num_blocks * num_blocks]);
for (int i = 0; i < num_blocks * num_blocks; ++i) {
cell_infos_[i].values = values_.get();
}
SetZero();
}
@@ -68,7 +73,7 @@ CellInfo* BlockRandomAccessDenseMatrix::GetCell(const int row_block_id,
*col = block_layout_[col_block_id];
*row_stride = num_rows_;
*col_stride = num_rows_;
return &cell_info_;
return &cell_infos_[row_block_id * block_layout_.size() + col_block_id];
}
// Assume that the user does not hold any locks on any cell blocks
@@ -84,10 +84,10 @@ class BlockRandomAccessDenseMatrix : public BlockRandomAccessMatrix {
double* mutable_values() { return values_.get(); }
private:
CellInfo cell_info_;
int num_rows_;
vector<int> block_layout_;
scoped_array<double> values_;
scoped_array<CellInfo> cell_infos_;
CERES_DISALLOW_COPY_AND_ASSIGN(BlockRandomAccessDenseMatrix);
};
-14
View File
@@ -1153,20 +1153,6 @@ LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options,
options->sparse_linear_algebra_library;
linear_solver_options.num_threads = options->num_linear_solver_threads;
// The matrix used for storing the dense Schur complement has a
// single lock guarding the whole matrix. Running the
// SchurComplementSolver with multiple threads leads to maximum
// contention and slowdown. If the problem is large enough to
// benefit from a multithreaded schur eliminator, you should be
// using a SPARSE_SCHUR solver anyways.
if ((linear_solver_options.num_threads > 1) &&
(linear_solver_options.type == DENSE_SCHUR)) {
LOG(WARNING) << "Warning: Solver::Options::num_linear_solver_threads = "
<< options->num_linear_solver_threads
<< " with DENSE_SCHUR will result in poor performance; "
<< "switching to single-threaded.";
linear_solver_options.num_threads = 1;
}
options->num_linear_solver_threads = linear_solver_options.num_threads;
linear_solver_options.use_block_amd = options->use_block_amd;
+1 -1
View File
@@ -561,7 +561,7 @@ TEST(SolverImpl, CreateLinearSolverDenseSchurMultipleThreads) {
SolverImpl::CreateLinearSolver(&options, &error));
EXPECT_TRUE(solver != NULL);
EXPECT_EQ(options.linear_solver_type, DENSE_SCHUR);
EXPECT_EQ(options.num_linear_solver_threads, 1);
EXPECT_EQ(options.num_linear_solver_threads, 2);
}
TEST(SolverImpl, CreateIterativeLinearSolverForDogleg) {