java code
public class Test {
public static void main(String[] args) {
final int n=1000;
final int m=1000;
final int p=1000;
final long startDate = System.currentTimeMillis();
final double[] A = new double[n*m];
final double[] B = new double[m*p];
final double[] C = new double[n*p];
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
A[i*m+j]=Math.random();
for (int i=0;i<m;i++)
for (int j=0;j<p;j++)
B[i*p+j]=Math.random();
for (int i=0;i<n;i++)
for (int j=0;j<p;j++) {
for (int k=0;k<m;k++)
C[i*p+j]+=A[i*m+k]*B[k*p+j];
}
System.out.println("Calculation time: " + (System.currentTimeMillis() - startDate));
}
}
public class Test {
public static void main(String[] args) {
final int n=1000;
final int m=1000;
final int p=1000;
final long startDate = System.currentTimeMillis();
final double[] A = new double[n*m];
final double[] B = new double[m*p];
final double[] C = new double[n*p];
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
A[i*m+j]=Math.random();
for (int i=0;i<m;i++)
for (int j=0;j<p;j++)
B[i*p+j]=Math.random();
for (int i=0;i<n;i++)
for (int j=0;j<p;j++) {
for (int k=0;k<m;k++)
C[i*p+j]+=A[i*m+k]*B[k*p+j];
}
System.out.println("Calculation time: " + (System.currentTimeMillis() - startDate));
}
}
Мега оптимизация (см. код) привела к выигрышу 6 (51760)(!!!) секунд. Вумная Java такую оптимизация и сама могла бы сделать (java оптимизации фууу)
public class Test {
public static void main(String[] args) {
final int n=1000;
final int m=1000;
final int p=1000;
final long startDate = System.currentTimeMillis();
final double[] A = new double[n*m];
final double[] B = new double[m*p];
final double[] C = new double[n*p];
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
A[i*m+j]=Math.random();
for (int i=0;i<m;i++)
for (int j=0;j<p;j++)
B[i*p+j]=Math.random();
for (int i=0;i<n;i++) {
final int k1 = i*m;
for (int j=0;j<p;j++) {
final int k2 = i*p+j;
for (int k=0;k<m;k++) {
C[k2] += A[k1+k]*B[k*p+j];
}
}
}
System.out.println("Calculation time: " + (System.currentTimeMillis() - startDate));
}
}
одно добавление. замена
final int k2 = i*p+j;
for (int k=0;k<m;k++) {
C[k2] += A[k1+k]*B[k*p+j];
}
на
final int k2 = i*p+j;
int _C = 0;
for (int k=0;k<m;k++) {
_C += A[k1+k]*B[k*p+j];
}
C[k2] = _C;
_увеливала_ время до 100 секунд. (ещё одно фууу - преведение стандартных типов на 2).
если там использовать double то время сокращается до 35165 и становится сравнимо с С.
В обшем давовский оптимизатор заработал два.
А так? :)
for (int i = 0; i < n; i++) {
for (int j = 0; j < p; j++) {
final int ipj = i * p + j;
final int im = i * m;
C[ipj] = 0;
int kpj = j;
for (int k = 0; k < m; k++) {
C[ipj] += A[im + k] * B[kpj];
kpj += p;
}
}
}
Сорри, умножение в 1-й цикл:
for (int i = 0; i < n; i++) {
final int im = i * m;
final int ip = i * p;
for (int j = 0; j < p; j++) {
final int ipj = ip + j;
C[ipj] = 0;
int kpj = j;
for (int k = 0; k < m; k++) {
C[ipj] += A[im + k] * B[kpj];
kpj += p;
}
}
}
s n,m,p = 1000 programma na C pokazala na 30% luchshe rezultat'. Pri uvelichenii n,m,p do 2000, C prodolzhal ostavatsya liderom, no uzhe s 10% operezheniem. GCJ pokazal sebya s otvratitelnoy storoni, ustupiv C 18%, java 7%.
Na toy zhe mashine pod solaris 10 rezultati java oboshli C pod linuxom na 25%, resultati C pod solarisom hotya i oboshli linux na 8%, vse ravno otstayut ot javi na 17%.