Tôi đang triển khai phép nhân C++ cho ma trận với các cấu trúc và kỹ thuật dữ liệu khác nhau (vectơ, mảng và OpenMP) và tôi tìm thấy một tình huống lạ ... phiên bản mảng đang làm việc tốt hơn:Tại sao phép nhân C++ với mảng động làm việc tốt hơn std :: phiên bản vector
lần:
OpenMP mult_1: thời gian: 5,882000 s
mảng mult_2: thời gian: 1,478000 s
cờ biên soạn của tôi là:
/usr/bin/g ++ -fopenmp -pthread -std = C++ 1n-O3
phiên bản C++ vector
typedef std::vector<std::vector<float>> matrix_f;
void mult_1 (const matrix_f & matrixOne, const matrix_f & matrixTwo, matrix_f & result) {
const int matrixSize = (int)result.size();
#pragma omp parallel for simd
for (int rowResult = 0; rowResult < matrixSize; ++rowResult) {
for (int colResult = 0; colResult < matrixSize; ++colResult) {
for (int k = 0; k < matrixSize; ++k) {
result[rowResult][colResult] += matrixOne[rowResult][k] * matrixTwo[k][colResult];
}
}
}
}
Phiên bản mảng động
void mult_2 (float * matrixOne, float * matrixTwo, float * result, int size) {
for (int row = 0; row < size; ++row) {
for (int col = 0; col < size; ++col) {
for (int k = 0; k < size; ++k) {
(*(result+(size*row)+col)) += (*(matrixOne+(size*row)+k)) * (*(matrixTwo+(size*k)+col));
}
}
}
}
.210
kiểm tra:
C++ phiên bản vector
utils::ChronoTimer timer;
/* set Up simple matrix */
utils::matrix::matrix_f matr1 = std::vector<std::vector<float>>(size,std::vector<float>(size));
fillRandomMatrix(matr1);
utils::matrix::matrix_f matr2 = std::vector<std::vector<float>>(size,std::vector<float>(size));
fillRandomMatrix(matr2);
utils::matrix::matrix_f result = std::vector<std::vector<float>>(size,std::vector<float>(size));
timer.init();
utils::matrix::mult_1(matr1,matr2,result);
std::printf("openmp mult_1: time: %f ms\n",timer.now()/1000);
mảng động phiên bản
utils::ChronoTimer timer;
float *p_matr1 = new float[size*size];
float *p_matr2 = new float[size*size];
float *p_result = new float[size*size];
fillRandomMatrixArray(p_matr1,size);
fillRandomMatrixArray(p_matr2,size);
timer.init();
utils::matrix::mult_2(p_matr1,p_matr2,p_result,size);
std::printf("array mult_2: time: %f ms\n",timer.now()/1000);
delete [] p_matr1;
delete [] p_matr2;
delete [] p_result;
Tôi đã kiểm tra một số bài viết trước đây, nhưng tôi không thể tìm thấy bất kỳ liên quan với tôi vấn đề link, link2, link3:
UPDATE: tôi refactorized thử nghiệm với các câu trả lời, và vector làm việc slighty tốt hơn:
vector mult: Thời gian: 1,194000 s
mảng mult_2: Thời gian: 1,202000 s
Phiên bản vector C++
void mult (const std::vector<float> & matrixOne, const std::vector<float> & matrixTwo, std::vector<float> & result, int size) {
for (int row = 0; row < size; ++row) {
for (int col = 0; col < size; ++col) {
for (int k = 0; k <size; ++k) {
result[(size*row)+col] += matrixOne[(size*row)+k] * matrixTwo[(size*k)+col];
}
}
}
}
động mảng phiên bản
void mult_2 (float * matrixOne, float * matrixTwo, float * result, int size) {
for (int row = 0; row < size; ++row) {
for (int col = 0; col < size; ++col) {
for (int k = 0; k < size; ++k) {
(*(result+(size*row)+col)) += (*(matrixOne+(size*row)+k)) * (*(matrixTwo+(size*k)+col));
}
}
}
}
Ngoài ra, phiên bản vectorized của tôi là làm việc tốt hơn (0,803 s);
Dữ liệu được sắp xếp khác nhau trong bộ nhớ. Các ma trận của bạn là tiếp giáp trong bộ nhớ trong khi thực hiện 'vector' phân bổ từng vector một cách riêng biệt. Nếu kích thước được cố định tại thời gian biên dịch, bạn có thể thử 'vector >' hoặc làm điều gì đó khác để đảm bảo rằng ma trận hoàn chỉnh nằm liền kề trong bộ nhớ. –
PeterT
Xem http://stackoverflow.com/questions/17259877/1d-or-2d-array-whats-faster về lý do tại sao bạn thường muốn tránh các cấu trúc 2d "thực" (như 'T **', 'vector> '...) để lưu trữ các ma trận dày đặc. –
Pixelchemist
Tôi sẽ đoán bố trí bộ nhớ không phải là vấn đề duy nhất của bạn. Hiển thị cho chúng tôi mã bộ đếm thời gian và số lượng chủ đề bạn đang chạy phiên bản openmp. – jepio