से बेहतर काम करता है मैं विभिन्न डेटा संरचनाओं और तकनीकों (वैक्टर, सरणी और ओपनएमपी) के साथ मैट्रिस के लिए सी ++ गुणा लागू कर रहा हूं और मुझे एक अजीब स्थिति मिली ... मेरी गतिशीलता सरणी संस्करण बेहतर काम कर रहा है:गतिशील सरणी के साथ सी ++ गुणा क्यों std :: वेक्टर संस्करण
बार:
OpenMP mult_1: समय: ५.८८२००० रों
सरणी mult_2: समय: १.४७८००० रों
मेरे संकलन झंडे हैं:
/usr/bin/जी ++ -fopenmp -pthread -std = C++ 1 वर्ष -O3
सी ++ वेक्टर संस्करण
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];
}
}
}
}
गतिशील सरणी संस्करण
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
परीक्षण:
सी ++ वेक्टर संस्करण
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);
गतिशील सरणी संस्करण
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;
मैं कुछ पिछले पोस्ट की जाँच की गई थी, लेकिन मैं किसी के साथ संबंधित नहीं पा सके मेरी समस्या link, link2, link3:
अद्यतन: मैं जवाब के साथ परीक्षण refactorized, और वेक्टर बेहतर slighty काम करता है:
वेक्टर mult: समय: १.१९४००० रों
सरणी mult_2: समय: १.२०२००० रों
सी ++ वेक्टर संस्करण
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];
}
}
}
}
गतिशील सरणी संस्करण
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));
}
}
}
}
इसके अलावा, मेरी vectorized संस्करण बेहतर (0.803 रों) काम कर रहा है;
डेटा स्मृति में अलग-अलग व्यवस्थित किया गया है। 'वेक्टर' करते समय मैट्रिक्स स्मृति में संगत होते हैं, प्रत्येक वेक्टर को अलग-अलग आवंटित करते हैं। यदि आकार संकलित समय पर तय किया गया है तो आप 'वेक्टर <सर >' का प्रयास कर सकते हैं या यह सुनिश्चित करने के लिए कुछ और कर सकते हैं कि पूर्ण मैट्रिक्स स्मृति में सम्मिलित है। –
PeterT
देखें http://stackoverflow.com/questions/17259877/1d-or-2d-array-whats- आप आमतौर पर "असली" 2 डी संरचनाओं (जैसे 'टी **', 'वेक्टर> से बचना चाहते हैं) '...) घने matrices भंडारण के लिए। –
Pixelchemist
मुझे लगता है कि मेमोरी लेआउट आपका एकमात्र मुद्दा नहीं है। हमें अपना टाइमर कोड दिखाएं और आप कितने धागे ओपनएमपी संस्करण को चला रहे हैं। – jepio