mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-29 08:34:37 +08:00
Multithread DENSE_SCHUR
Replace the global lock in BlockRandomAccessDenseMatrix with a per cell lock. Change-Id: Iddbe38616157b6e0d3770eede3335a056c3ba18c
This commit is contained in:
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user