К вопросу о «кроссплатформенной» разработке.
Есть такой фрагмент кода (сильно порезанный кусок, можно ещё сильнее порезать, но на нём демонстрируется проблема):
// g++ -Ofast -ffast-math
#include <cstdio>
#include <cstdlib>
#include <cmath>
int main() {
const int N = 1200;
double* A;
double* B;
double C;
int m;
A = new double[N*N];
B = new double[N];
//srand(time(0));
//srand( (unsigned)time( NULL ) );
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
A[N*i+j] = (double)rand() / ((double)10000);
}
B[i] = 0.0;
}
// Сильно порезанный фрагмент кода:
for (int k = 0; k < N-1; k++ ) {
m = (k + 1);
for (int i = k + 1; i < N; i++ ) {
if ( fabs(A[N*(i) + (k)]) > fabs(A[N*(m-1) + k]) ) m = (i + 1);
}
B[k] = m;
if ( (m + 1) != k ) B[N-1] = -B[N-1];
C = A[N*(m-1) + k];
A[N*(m-1) + k] = A[N*k + k];
A[N*k + k] = C;
if (C == 0) continue;
for (int i = k + 1; i < N; i++ ) A[N*i + k] = -A[N*i + k]/C;
for (int j = k + 1; j < N; j++ ) {
C = A[N*(m-1)+ j];
A[N*(m-1) + j] = A[N*k + j];
A[N*k + j] = C;
if ( C != 0 ) {
// дольше всего выполняется этот блок цикла:
for (int i = k + 1; i < N; i++ ) {
A[N*i + j] = A[N*i + j] + A[N*i + k]*C;
}
}
}
}
delete [] A;
delete [] B;
return 0;
}
Суть проблемы в том, что собранный с одинаковыми опциями этот кусок выполняется на моём железе в Linux за 2.7 сек (gcc 4.8.4), а в Windows7 (mingw64 4.9.3, tdm-gcc 4.9.2) за 8.4 (т.е. разница ~3 раза). Ни на одном другом примере я такого проседания не наблюдал (разве что TDM-GCC генерит в некоторых случаях код заметно быстрее чем MinGW64, но не в этом случае). Понятно, что в этом блоке, который третий по вложенности цикл
for (int i = k + 1; i < N; i++ ) {
A[N*i + j] = A[N*i + j] + A[N*i + k]*С;
}
Сталкивался ли кто с подобным поведением MinGW64, TDM-GCCd в плане сильного проседания производительности? Какие ещё ключи компилятора могут заметно ускорить выполнение этого фрагмента?