У меня мало опыта в параллельном программировании, и мне было интересно, может ли кто-нибудь быстро взглянуть на кусок кода, который я написал, и посмотреть, есть ли какие-либо очевидные способы повышения эффективности вычислений.
Сложность возникает из-за того, что у меня есть несколько матричных операций разной размерности, которые мне нужно вычислить, поэтому я не уверен, что это наиболее сжатый способ кодирования вычислений.
Ниже мой код. Обратите внимание, что этот код работает. Матрицы, с которыми я работаю, имеют размер примерно 700x700 [см. int s ниже] или 700x30 [int n].
Кроме того, я использую библиотеку броненосца для своего последовательного кода. Может случиться так, что распараллеливание с использованием openMP, но с сохранением матричных классов броненосца будет медленнее, чем стандартная библиотека по умолчанию; есть ли у кого-нибудь мнение по этому поводу (прежде чем я потрачу часы на капитальный ремонт!)?
double start, end, dif;
int i,j,k; // iteration counters
int s,n; // matrix dimensions
mat B; B.load(...location of stored s*n matrix...) // input objects loaded from file
mat I; I.load(...s*s matrix...);
mat R; R.load(...s*n matrix...);
mat D; D.load(...n*n matrix...);
double e = 0.1; // scalar parameter
s = B.n_rows; n = B.n_cols;
mat dBdt; dBdt.zeros(s,n); // object for storing output of function
// 100X sequential computation using Armadillo linear algebraic functionality
start = omp_get_wtime();
for (int r=0; r<100; r++) {
dBdt = B % (R - (I * B)) + (B * D) - (B * e);
}
end = omp_get_wtime();
dif = end - strt;
cout << "Seq computation: " << dBdt(0,0) << endl;
printf("relaxation time = %f", dif);
cout << endl;
// 100 * parallel computation using OpenMP
omp_set_num_threads(8);
for (int r=0; r<100; r++) {
// parallel computation of I * B
#pragma omp parallel for default(none) shared(dBdt, B, I, R, D, e, s, n) private(i, j, k) schedule(static)
for (i = 0; i < s; i++) {
for (j = 0; j < n; j++) {
for (k = 0; k < s; k++) {
dBdt(i, j) += I(i, k) * B(k, j);
}
}
}
// parallel computation of B % (R - (I * B))
#pragma omp parallel for default(none) shared(dBdt, B, I, R, D, e, s, n) private(i, j) schedule(static)
for (i = 0; i < s; i++) {
for (j = 0; j < n; j++) {
dBdt(i, j) = R(i, j) - dBdt(i, j);
dBdt(i, j) *= B(i, j);
dBdt(i, j) -= B(i, j) * e;
}
}
// parallel computation of B * D
#pragma omp parallel for default(none) shared(dBdt, B, I, R, D, e, s, n) private(i, j, k) schedule(static)
for (i = 0; i < s; i++) {
for (j = 0; j < n; j++) {
for (k = 0; k < n; k++) {
dBdt(i, j) += B(i, k) * D(k, j);
}
}
}
}
end = omp_get_wtime();
dif = end - strt;
cout << "OMP computation: " << dBdt(0,0) << endl;
printf("relaxation time = %f", dif);
cout << endl;
Если я использую Hyper-Threading 4 ядра, я получаю следующий результат:
Seq computation: 5.54926e-10
relaxation time = 0.130031
OMP computation: 5.54926e-10
relaxation time = 2.611040
Это говорит о том, что хотя оба метода дают одинаковый результат, параллельная формулировка примерно в 20 раз медленнее, чем последовательная.
Возможно, что для матриц такого размера накладные расходы, связанные с этой проблемой «переменной размерности», перевешивают преимущества распараллеливания. Любые идеи будут высоко оценены.
Заранее спасибо,
Джек
BD
, ниIB
не являются Матричными цепочками. Лучше бы сосредоточились скорее на основных проблемах. - person user3666197   schedule 07.09.2017