#c #c #eigen
#c #c #eigen
Вопрос:
Я читаю некоторые учебники по программированию на C, чтобы освежить их, и одна из главных причин, по которой мне лично нравился C , а не C (для моего типа программ), — это собственная линейная алгебра. Итак, сегодня я просто провел простой тест умножения матриц 10×10 и измерил время, и, что удивительно, по крайней мере, для меня, было показано, что стиль C работает довольно быстрее. В режиме выпуска я усредняю <1 мс для C и ~ 12 мс для собственного
Имеет ли смысл, что это так, и если да (или нет), почему? Я ни в коем случае не дискредитирую Eigen, все еще моя лучшая библиотека линейной алгебры, и она предоставляет множество других функций. И, как заядлый пользователь Eigen, есть ли что-то, что можно сделать для повышения производительности в sitatutions, подобных показанному ниже.
// function to multiply two matrices
void multiplyMatrices(int first[][10],
int second[][10],
int result[][10],
int r1, int c1, int r2, int c2) {
// Multiplying first and second matrices and storing it in result
for (int i = 0; i < r1; i) {
for (int j = 0; j < c2; j) {
// Init matrix
result[i][j] = 0;
for (int k = 0; k < c1; k) {
result[i][j] = first[i][k] * second[k][j];
}
}
}
}
int main() {
int first[10][10], second[10][10], result[10][10];
// Initializing elements to something arbitrary
for (int i = 0; i < 10; i ) {
for (int j = 0; j < 10; j ) {
first[i][j] = i * j;
second[i][j] = (i 3) * j;
}
}
// multiply two matrices, only time the multiplication
auto t1 = std::chrono::high_resolution_clock::now();
multiplyMatrices(first, second, result, 10, 10, 10, 10);
auto t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
std::cout << "C style: " << duration << std::endl;
// Initialize the matrices to a fixed size
Eigen::Matrix<int, 10, 10> f1(10, 10);
Eigen::Matrix<int, 10, 10> f2(10, 10);
Eigen::Matrix<int, 10, 10> r(10, 10);
// Same initialization values as C style
for (int i = 0; i < 10; i ) {
for (int j = 0; j < 10; j ) {
f1(i, j) = i * j;
f2(i, j) = (i 3) * j;
}
}
// Only time the multiplication
t1 = std::chrono::high_resolution_clock::now();
r = f1 * f2;
t2 = std::chrono::high_resolution_clock::now();
duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
std::cout << "Eigen: " << duration << std::endl;
Комментарии:
1. Попробуйте поместить случайные значения в матрицы. То, как вы инициализируете матрицы, компилятор может вычислить результат и пропустить все умножение во время выполнения.
2. Вы смотрели на asm, чтобы увидеть, не полностью ли он встроен в первый код? (так что никаких вычислений вообще).
3. @Barmar Я снова запустил его, инициализируя rand() для всех матриц, и получил аналогичные результаты, C ~ 1 мс, а собственный немного медленнее ~ 20 мс
4. Согласно некоторым быстрым проверкам, собственное умножение выполняется примерно вдвое быстрее, а
multiplyMatrices
не в 12-20 раз медленнее. этот тестовый пример теперь выполняется 100 раз . (это не научные результаты). Вы рассчитываете время с оптимизацией?5. в этом вопросе нет ничего о C, не помечайте без разбора