Small Beamformer optimization

* Don't use ConjugateDotProduct to calculate the norm.
* Only resize Matrix when needed.

This makes the Beamformer run in 93.6% the original time.
The error between the new and original output is really small and is caused by the new norm calculation.

R=andrew@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/37339004

Cr-Commit-Position: refs/heads/master@{#8438}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8438 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
aluebs@webrtc.org 2015-02-19 19:02:17 +00:00
parent cce874b8d2
commit 661af50dd5
2 changed files with 25 additions and 22 deletions

View File

@ -95,9 +95,7 @@ float Norm(const ComplexMatrix<float>& mat,
for (int i = 0; i < norm_mat.num_columns(); ++i) { for (int i = 0; i < norm_mat.num_columns(); ++i) {
for (int j = 0; j < norm_mat.num_columns(); ++j) { for (int j = 0; j < norm_mat.num_columns(); ++j) {
complex<float> cur_norm_element = conj(norm_mat_els[0][j]); first_product += conj(norm_mat_els[0][j]) * mat_els[j][i];
complex<float> cur_mat_element = mat_els[j][i];
first_product += cur_norm_element * cur_mat_element;
} }
second_product += first_product * norm_mat_els[0][i]; second_product += first_product * norm_mat_els[0][i];
first_product = 0.f; first_product = 0.f;
@ -140,6 +138,19 @@ float SumAbs(const ComplexMatrix<float>& mat) {
return sum_abs; return sum_abs;
} }
// Calculates the sum of squares of a complex matrix.
float SumSquares(const ComplexMatrix<float>& mat) {
float sum_squares = 0.f;
const complex<float>* const* mat_els = mat.elements();
for (int i = 0; i < mat.num_rows(); ++i) {
for (int j = 0; j < mat.num_columns(); ++j) {
float abs_value = std::abs(mat_els[i][j]);
sum_squares += abs_value * abs_value;
}
}
return sum_squares;
}
} // namespace } // namespace
Beamformer::Beamformer(const std::vector<Point>& array_geometry) Beamformer::Beamformer(const std::vector<Point>& array_geometry)
@ -332,8 +343,7 @@ void Beamformer::ProcessAudioBlock(const complex_f* const* input,
// angle. // angle.
for (int i = low_average_start_bin_; i < high_average_end_bin_; ++i) { for (int i = low_average_start_bin_; i < high_average_end_bin_; ++i) {
eig_m_.CopyFromColumn(input, i, num_input_channels_); eig_m_.CopyFromColumn(input, i, num_input_channels_);
float eig_m_norm_factor = float eig_m_norm_factor = std::sqrt(SumSquares(eig_m_));
std::sqrt(ConjugateDotProduct(eig_m_, eig_m_)).real();
if (eig_m_norm_factor != 0.f) { if (eig_m_norm_factor != 0.f) {
eig_m_.Scale(1.f / eig_m_norm_factor); eig_m_.Scale(1.f / eig_m_norm_factor);
} }

View File

@ -76,7 +76,7 @@ class Matrix {
// Copies |data| into the new Matrix. // Copies |data| into the new Matrix.
Matrix(const T* data, int num_rows, int num_columns) Matrix(const T* data, int num_rows, int num_columns)
: num_rows_(num_rows), num_columns_(num_columns) { : num_rows_(0), num_columns_(0) {
CopyFrom(data, num_rows, num_columns); CopyFrom(data, num_rows, num_columns);
scratch_data_.resize(num_rows_ * num_columns_); scratch_data_.resize(num_rows_ * num_columns_);
scratch_elements_.resize(num_rows_); scratch_elements_.resize(num_rows_);
@ -91,15 +91,8 @@ class Matrix {
// Copy |data| into the Matrix. The current data is lost. // Copy |data| into the Matrix. The current data is lost.
void CopyFrom(const T* const data, int num_rows, int num_columns) { void CopyFrom(const T* const data, int num_rows, int num_columns) {
num_rows_ = num_rows; Resize(num_rows, num_columns);
num_columns_ = num_columns; memcpy(&data_[0], data, num_rows_ * num_columns_ * sizeof(data_[0]));
size_t size = num_rows_ * num_columns_;
data_.assign(data, data + size);
elements_.resize(num_rows_);
for (int i = 0; i < num_rows_; ++i) {
elements_[i] = &data_[i * num_columns_];
}
} }
Matrix& CopyFromColumn(const T* const* src, int column_index, int num_rows) { Matrix& CopyFromColumn(const T* const* src, int column_index, int num_rows) {
@ -112,9 +105,11 @@ class Matrix {
} }
void Resize(int num_rows, int num_columns) { void Resize(int num_rows, int num_columns) {
num_rows_ = num_rows; if (num_rows != num_rows_ || num_columns != num_columns_) {
num_columns_ = num_columns; num_rows_ = num_rows;
Resize(); num_columns_ = num_columns;
Resize();
}
} }
// Accessors and mutators. // Accessors and mutators.
@ -136,8 +131,7 @@ class Matrix {
// Matrix Operations. Returns *this to support method chaining. // Matrix Operations. Returns *this to support method chaining.
Matrix& Transpose() { Matrix& Transpose() {
CopyDataToScratch(); CopyDataToScratch();
std::swap(num_rows_, num_columns_); Resize(num_columns_, num_rows_);
Resize();
return Transpose(scratch_elements()); return Transpose(scratch_elements());
} }
@ -278,8 +272,7 @@ class Matrix {
CHECK_EQ(num_columns_, rhs.num_rows_); CHECK_EQ(num_columns_, rhs.num_rows_);
CopyDataToScratch(); CopyDataToScratch();
num_columns_ = rhs.num_columns_; Resize(num_rows_, rhs.num_columns_);
Resize();
return Multiply(scratch_elements(), rhs.num_rows_, rhs.elements()); return Multiply(scratch_elements(), rhs.num_rows_, rhs.elements());
} }