LINUX.ORG.RU
решено ФорумTalks

Давайте померяемся (benchmark для умножения матриц)


0

0

Написал когда-то давно benchmark для умножения матриц.
Интересно, как результаты зависят от машины.
Попробуйте на самых разных машинах, скажите, что выдала программа, версию компилятора, и скажите на какой машине это вычислено.

%--- This software is Public Domain, author: pacify
%--- solid-linux.org.ru.c
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>

#define M 500
#define N 500
#define FXX double

#define DEFM1(A) FXX A[M*N]
#define ADDR1(A,i,j) A[i*N+j]
#define KILL1(A,B,C)
#define INIT1(A,B,C) \
    for (i=M-1;i>0;i--) for (j=N-1;j>0;j--) ADDR1(C,i,j) = 0; \
    for (i=M-1;i>0;i--) for (j=N-1;j>0;j--) ADDR1(A,i,j) = ADDR1(B,i,j) = (i*j)/(FXX)(M*N);
#define CALC1 for (i=M-1;i>0;i--) for (j=N-1;j>0;j--) { TMP1=0; for (k=N-1;k>0;k--) TMP1 += ADDR1(A1,i,k) * ADDR1(B1,k,j); ADDR1(C1,i,j) = TMP1;}
#define SUMM1 SUM1=0; for (i=M-1;i>0;i--) for (j=N-1;j>0;j--) SUM1+=ADDR1(C1,i,j);

#define DEFM2(A) FXX A[M][N]
#define ADDR2(A,i,j) A[i][j]
#define KILL2(A,B,C)
#define INIT2(A,B,C) \
    for (i=M-1;i>0;i--) for (j=N-1;j>0;j--) ADDR2(C,i,j) = 0; \
    for (i=M-1;i>0;i--) for (j=N-1;j>0;j--) ADDR2(A,i,j) = ADDR2(B,i,j) = (i*j)/(FXX)(M*N);
#define CALC2 for (i=M-1;i>0;i--) for (j=N-1;j>0;j--) { TMP2=0; for (k=N-1;k>0;k--) TMP2 += ADDR2(A2,i,k) * ADDR2(B2,k,j); ADDR2(C2,i,j) = TMP2;}
#define SUMM2 SUM2=0; for (i=M-1;i>0;i--) for (j=N-1;j>0;j--) SUM2+=ADDR2(C2,i,j);

int main (int argc, char **argv) {
    DEFM1(A1); DEFM1(B1); DEFM1(C1);
    DEFM2(A2); DEFM2(B2); DEFM2(C2);
    unsigned int i;
    register unsigned int j,k;
    register FXX TMP1,TMP2;
    FXX SUM1,SUM2;
    clock_t T1,T2,T3,T4;
    double delta,d1,d2,d3,d4;
    INIT1(A1,B1,C1) T1=clock(); CALC1 T2=clock(); SUMM1
    INIT2(A2,B2,C2) T3=clock(); CALC2 T4=clock(); SUMM2
    KILL1(A1,B1,C1) KILL2(A2,B2,C2)
    delta=((double)((T4-T3)-(T2-T1)))/CLOCKS_PER_SEC;
    d1=((double)((T2-T1)))/CLOCKS_PER_SEC;
    d2=((double)((T4-T3)))/CLOCKS_PER_SEC;
    printf("%7d%7d%7d",M,N,(M*N));
    printf("%12.5lf%12.5lf%12.5lf",d1,d2,delta);
    printf("%15.7E%15.7E",SUM1/(M*N),SUM2/(M*N));
    printf("\n");
    return 0;
}

%--- Makefile-linux.org.ru

NAME = solid-linux.org.ru
OPTS = -O7 -fforce-mem -ffast-math -fstrength-reduce
GCC  = gcc

result : ${NAME}.c
        ${GCC} -S ${OPTS} -o ${NAME}.S ${NAME}.c
        ${GCC} ${OPTS} -o ${NAME} ${NAME}.c
        strip --strip-all ${NAME}

%--- что набрать в командной строке

% make -f Makefile-linux.org.ru
% ulimit -s 65536
% ./solid-linux.org.ru

%--- END
★★★★★

Duron 700, gcc-3.3.5
500 500 250000 10.40000 10.45000 0.05000 4.1375749E+01 4.1375749E+01

pacify ★★★★★
() автор топика
Ответ на: комментарий от owlfog

ах да.

Linux insite 2.6.18-gentoo-r6 #1 SMP Tue Jan 9 16:34:37 YEKT 2007 i686 Intel(R) Pentium(R) 4 CPU 3.40GHz GenuineIntel GNU/Linux

owlfog
()

Intel Celeron 1200 (Tualatin) / FreeBSD 5.4 / gcc 3.4.2

500 500 250000 2.67969 2.593753355443  1.91406  4.1375749E+01  4.1375749E+01

dumka ★★
()
Ответ на: комментарий от beastie

Linux 2.6.17-10-generic #2 SMP Tue Dec 5 22:28:26 UTC 2006 i686 GNU/Linux
model name      : Intel(R) Pentium(R) M processor 1.70GHz
gcc (GCC) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)

    500    500 250000     0.98000     1.13000     0.15000  4.1375749E+01  4.1375749E+01

OpenBSD 4.0 BLUE#10 i386
hw.model=AMD Athlon(tm) XP 2200+ ("AuthenticAMD" 686-class, 256KB L2 cache)
gcc (GCC) 3.3.5 (propolice)

    500    500 250000     2.17000     2.18000     0.01000  4.1375749E+01  4.1375749E+01

beastie ★★★★★
()

[birdie@localhost test]$ ./solid-linux.org.ru
Segmentation fault


gdb ./solid-linux.org.ru
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0x0804841d in ?? ()

birdie ★★★★★
()

CPU: AMD Athlon(tm) XP 2200+
RAM: 512MB
500 500 250000 2.44000 2.41000 -0.03000 4.1375749E+01 4.1375749E+01

CPU: Intel(R) Celeron(R) CPU 2.13GHz
RAM: 512MB
500 500 250000 2.29000 2.16000 -0.13000 4.1375749E+01 4.1375749E+01

CPU: Intel(R) Celeron(R) CPU 2.53GHz
RAM: 512MB
500 500 250000 2.25000 2.06000 -0.19000 4.1375749E+01 4.1375749E+01

CPU: Intel(R) Pentium(R) 4 CPU 2.40GHz
RAM: 1024MB
500 500 250000 1.59000 1.60000 0.01000 4.1375749E+01 4.1375749E+01

CPU: 2x(Intel(R) Xeon(R) CPU 5110 @ 1.60GHz dualcore)
RAM: 4096MB
500 500 250000 0.94000 1.03000 0.09000 4.1375749E+01 4.1375749E+01

CPU: AMD Athlon(tm) 64 Processor 3200+
RAM: 1024MB
500 500 250000 0.77000 0.72000 -0.05000 4.1375749E+01 4.1375749E+01

anonymous
()

shaman@bondarenko:/tmp/111$ ./solid-linux.org.ru
500 500 250000 1.08000 1.12000 0.04000 4.1375749E+01 4.1375749E+01
shaman@bondarenko:/tmp/111$ uname -a
Linux bondarenko.avp.ru 2.6.19-1.2895.fc6 #1 SMP Wed Jan 10 19:28:18 EST 2007 i686 i686 i386 GNU/Linux
shaman@bondarenko:/tmp/111$ cat /proc/cpuinfo |grep Pe
model name : Intel(R) Pentium(R) D CPU 3.40GHz
model name : Intel(R) Pentium(R) D CPU 3.40GHz
shaman@bondarenko:/tmp/111$

Shaman007 ★★★★★
()
Ответ на: комментарий от Shaman007

shaman@bondarenko:~$ gcc --version
gcc (GCC) 4.1.1 20070105 (Red Hat 4.1.1-51)
Copyright (C) 2006 Free Software Foundation, Inc.

Shaman007 ★★★★★
()

Такой быдлокод даже пытаться компилить не стану.

anonymous
()
Ответ на: комментарий от anonymous

    500    500 250000     0.65000     0.70000     0.05000  4.1375749E+01  4.1375749E+01
    500    500 250000     0.64000     0.70000     0.06000  4.1375749E+01  4.1375749E+01
    500    500 250000     0.65000     0.70000     0.05000  4.1375749E+01  4.1375749E+01
    500    500 250000     0.65000     0.69000     0.04000  4.1375749E+01  4.1375749E+01

birdie ★★★★★
()

uname: 2.6.19-1.2895.fc6
gcc --version: gcc (GCC) 4.1.1 20070105 (Red Hat 4.1.1-51)
CPU: core 2 duo 6600
результаты:
500 500 250000 0.67000 0.67000 0.00000 4.1375749E+01 4.1375749E+01

jr_A
()

> pacify

Ты хоть объясни что за цифры твоя программа выдаёт. Где длина пиписьки?

birdie ★★★★★
()

Pentium D 805, 512 Ram

500 500 250000 1.43000 1.42000 -0.01000 4.1375749E+01 4.1375749E+01

uname -a

Linux server 2.6.15-27-686 #1 SMP PREEMPT Fri Dec 8 18:00:07 UTC 2006 i686 GNU/Linux

Motiv_studenta ★★
()
Ответ на: комментарий от birdie

>Где длина пиписьки?

и выводить эту длину надо не в цифрах, а примерно так:

int i;
putchar('8');
for(i=0;i<dlina;++i)
putchar('=');
putchar('D');

Deleted
()

$ ./solid-linux.org.ru
    500    500 250000     0.54000     0.54000     0.00000  4.1375749E+01  4.1375749E+01
$ grep 'model name' /proc/cpuinfo
model name      : Dual Core AMD Opteron(tm) Processor 280
model name      : Dual Core AMD Opteron(tm) Processor 280
model name      : Dual Core AMD Opteron(tm) Processor 280
model name      : Dual Core AMD Opteron(tm) Processor 280
$ gcc --version|head -1
gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-3)

Deleted
()
Ответ на: комментарий от birdie

> 500 500 250000 0.65000 0.70000 0.05000 4.1375749E+01 4.1375749E+01

Чем меньше числа "0.65000 0.70000" (время прохода в секундах), тем больше пиписька (в метрах), "0.05000" - это дельта по времени.
Первое - это время умножения матриц 500x500 при адресации типа A[i*N+j],
второе - при адресации A[i][j].
Обычно первое меньше второго, т.е. адресация A[i*N+j] немного выгоднее (заметно на старых машинах).
Но вот у товарища owlfog выдался противоположный результат.

pacify ★★★★★
() автор топика
Ответ на: комментарий от owlfog

owlfog, а ты можешь повторить измерения раз пять ?
Если дельта будет все-равно отрицательной, скинь сюда .S-файл.

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

Когда ты создаешь массив как A[500][500] никакой двойной адресации нет, так как элементы лежат последовательно. С таким массивом можно работать и так (&A[0][0])[i * M + j]

Reset ★★★★★
()
Ответ на: комментарий от pacify

А вообще ты бы лучше не позорился такой код сюда постить. Страшно смотреть на это убожество. И матрицы ты умножаешь неправильно - забыл про нулевой элемент.

Reset ★★★★★
()
Ответ на: комментарий от pacify

и то о чем ты говоришь должно быть как раз заметно на новых машиных, так как раньше разрыв между скоростью памяти и проца был не таким большим :)

Reset ★★★★★
()
Ответ на: комментарий от Reset

> А вообще ты бы лучше не позорился такой код сюда постить. Страшно смотреть на это убожество.

Мне такой код нравится. А ты, если можешь, приведи пример кода как надо писать, а ?

> И матрицы ты умножаешь неправильно - забыл про нулевой элемент.

Точно.

pacify ★★★★★
() автор топика

Это что получается, семтрон 3400 быстрее core2duo? Тут какая-то неточность. Напишите кто-нибудь многопоточный тест

Motiv_studenta ★★
()
Ответ на: комментарий от Motiv_studenta

> Это что получается, семтрон 3400 быстрее core2duo?

Зависть заела? ;-) Тут вопрос в правильно подобранной памяти, а также не забывайте про латентность, которая у AMD много ниже из-за встроенного контроллера памяти.

anonymous
()
Ответ на: комментарий от pacify

>> И матрицы ты умножаешь неправильно - забыл про нулевой элемент.
> Точно.

Хотя, вспомнил. Нулевые элементы выброшены, так как:
ADDR2(A,i,j) = ADDR2(B,i,j) = (i*j)/(FXX)(M*N);
и их можно не учитывать в при суммировании.

pacify ★★★★★
() автор топика
Ответ на: комментарий от anonymous

>Зависть заела? ;-) Тут вопрос в правильно подобранной памяти, а также не забывайте про латентность, которая у AMD много ниже из-за встроенного контроллера памяти.

Да нет, я хорошо помню свои субъективные ощушения. P4 1.8 был в реальной жизни намного быстрей новенького Semptron 2800+ ;)

Motiv_studenta ★★
()

SunOS 5.10 , Intel Pentium 4 640, 3200 MHz (16 x 200), gcc 3.4.5:

500 500 250000 1.26000 1.25000 -0.01000 4.1375749E+01 4.1375749E+01

anonymous
()

Dual CPU P3-750Mhz (7.5x100)
SDRAM (100Mhz)

gcc-3.4.6

$ ./solid-linux.org.ru 
   500    500 250000     3.23000     3.24000     0.01000  4.1375749E+01  4.1375749E+01

$ ./solid-linux.org.ru & \
  ./solid-linux.org.ru & \
  ./solid-linux.org.ru & \
  ./solid-linux.org.ru &

   500    500 250000     4.33000     4.24000    -0.09000  4.1375749E+01  4.1375749E+01
   500    500 250000     4.25000     4.36000     0.11000  4.1375749E+01  4.1375749E+01
   500    500 250000     4.53000     4.47000    -0.06000  4.1375749E+01  4.1375749E+01
   500    500 250000     4.34000     4.02000    -0.32000  4.1375749E+01  4.1375749E+01

gcc-4.1.2
$ ./solid-linux.org.ru 
   500    500 250000     3.26000     3.33000     0.07000  4.1375749E+01  4.1375749E+01

$ ./solid-linux.org.ru & \
  ./solid-linux.org.ru & \
  ./solid-linux.org.ru & \
  ./solid-linux.org.ru &

   500    500 250000     4.65000     4.50000    -0.15000  4.1375749E+01  4.1375749E+01
   500    500 250000     4.61000     4.58000    -0.03000  4.1375749E+01  4.1375749E+01
   500    500 250000     4.62000     4.53000    -0.09000  4.1375749E+01  4.1375749E+01
   500    500 250000     4.72000     4.67000    -0.05000  4.1375749E+01  4.1375749E+01

sdio ★★★★★
()

uname -a: Linux riphome 2.6.17-gentoo-r5_RIP4 #1 Mon Oct 2 04:18:39 EEST 2006 i686 AMD Athlon(tm) XP 2400+ AuthenticAMD GNU/Linux

(на самом деле разогнанный Athlon XP 1800+@2GHz)

gcc --version: gcc (GCC) 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.9)

output: 500 500 250000 2.02000 2.02000 0.00000 4.1375749E+01 4.1375749E+01

rip_someday
()

Кластер:
$uname -a
Linux n04 2.6.13-15.12-smp #1 SMP Thu Aug 24 11:23:58 UTC 2006 x86_64 x86_64 x86_64 GNU/Linux
$less /etc/SuSE-release
SUSE LINUX 10.0 (X86-64)
VERSION = 10.0
gcc (GCC) 4.0.2 20050901 (prerelease) (SUSE Linux)
icc (ICC) 9.0  20050430 (с опциями, конечно, непонятки):
$make
icc -S -O7 -fforce-mem -ffast-math -fstrength-reduce -o solid-linux.org.ru.S sol
id-linux.org.ru.c
icc: Command line warning: ignoring option '-O'; no argument required
icc: Command line warning: ignoring unknown option '-fforce-mem'
icc: Command line warning: ignoring unknown option '-ffast-math'
icc: Command line warning: ignoring unknown option '-fstrength-reduce'
icc -O7 -fforce-mem -ffast-math -fstrength-reduce -o solid-linux.org.ru solid-li
nux.org.ru.c
icc: Command line warning: ignoring option '-O'; no argument required
icc: Command line warning: ignoring unknown option '-fforce-mem'
icc: Command line warning: ignoring unknown option '-ffast-math'
icc: Command line warning: ignoring unknown option '-fstrength-reduce'

Двухголовый Оптерон (2xsinglecore,2191.106 MHz):
$grep 'model name' /proc/cpuinfo
model name      : AMD Opteron(tm) Processor 248
model name      : AMD Opteron(tm) Processor 248
gcc:
500    500 250000     0.61000     0.67000     0.06000  4.1375749E+01 4.1375749E+01
icc:
500    500 250000     0.63000     0.98000     0.35000   4.1375749E+01  4.1375749E+01

Двухголовый Dual Core Opteron (2600.532 MHz):
$grep 'model name' /proc/cpuinfo
model name      : Dual-Core AMD Opteron(tm) Processor 2218
model name      : Dual-Core AMD Opteron(tm) Processor 2218
model name      : Dual-Core AMD Opteron(tm) Processor 2218
model name      : Dual-Core AMD Opteron(tm) Processor 2218
gcc:
500    500 250000     0.50000     0.57000     0.07000  4.1375749E+01  4.1375749E+01
icc:
500    500 250000     0.52000     0.89000     0.37000  4.1375749E+01  4.1375749E+01

Четырехголовый Dual Core Opteron (2406.079 MHz):
grep 'model name' /proc/cpuinfo
model name      : Dual Core AMD Opteron(tm) Processor 880
model name      : Dual Core AMD Opteron(tm) Processor 880
model name      : Dual Core AMD Opteron(tm) Processor 880
model name      : Dual Core AMD Opteron(tm) Processor 880
model name      : Dual Core AMD Opteron(tm) Processor 880
model name      : Dual Core AMD Opteron(tm) Processor 880
model name      : Dual Core AMD Opteron(tm) Processor 880
model name      : Dual Core AMD Opteron(tm) Processor 880
gcc:
500    500 250000     0.59000     0.69000     0.10000  4.1375749E+01  4.1375749E+01
icc:
500    500 250000     0.61000     1.05000     0.44000  4.1375749E+01  4.1375749E+01

Die-Hard ★★★★★
()
Ответ на: комментарий от anonymous

Гм... у Core 2 Duo 6600 кеш 4Mb, у Semptron 3400 в разы меньше (по моему в 8 раз). Поэтому в данном тесте вопрос латентности памяти не совсем уместен.

jr_A
()

SGI Altix 3700 32xItanium-2 1300MHz,
$uname -a
Linux 2.4.21-sgi302r24 #1 SMP

icc 8.0 (compiled: icc -fast):
500    500 250000     0.63830     0.62757    -0.01074  4.1375749E+01  4.1375749E+01
500    500 250000     0.62952     0.63733     0.00781  4.1375749E+01  4.1375749E+01
500    500 250000     0.63538     0.62757    -0.00781  4.1375749E+01  4.1375749E+01
500    500 250000     0.63928     0.62464    -0.01464  4.1375749E+01  4.1375749E+01
500    500 250000     0.63050     0.63245     0.00195  4.1375749E+01  4.1375749E+01

gcc (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-34):
500    500 250000     2.01934     1.74899    -0.27035  4.1375749E+01  4.1375749E+01
500    500 250000     2.01739     1.75778    -0.25962  4.1375749E+01  4.1375749E+01
500    500 250000     2.02032     1.75485    -0.26547  4.1375749E+01  4.1375749E+01

Die-Hard ★★★★★
()
Ответ на: комментарий от jr_A

Слегка обновленные результаты(погасил Xorg, и прочую ненужную хренотень):
500 500 250000 0.63000 0.64000 0.01000 4.1375749E+01 4.1375749E+01

[~@home tests]$ grep "model name" /proc/cpuinfo
model name : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz
model name : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz
[~@home tests]$ uname -r
2.6.19-1.2895.fc6
[~@home tests]$ gcc --version
gcc (GCC) 4.1.1 20070105 (Red Hat 4.1.1-51)

jr_A
()

OSF1 V5.1 1885 alpha,
$/usr/sbin/psrinfo -v
Status of processor 0 as of: 02/09/07 17:02:25
  Processor has been on-line since 08/17/2006 10:30:10
  The alpha EV6.7 (21264A) processor operates at 667 MHz,
  has a cache size of 4194304 bytes,
  and has an alpha internal floating point processor.

gcc 2.95.3:
500    500 250000     4.83314     4.61648    -0.21666  4.1375749E+01  4.1375749E+01

cxx -fast (cxx -V: Compiler Driver V6.3-002 )
500    500 250000     4.73314     4.51649    -0.21666  4.1375749E+01  4.1375749E+01

Die-Hard ★★★★★
()

500 500 250000 1.02000 0.96000 -0.06000 4.1375749E+01 4.1375749E+01

2.6.17-10-generic #2 SMP Tue Dec 5 22:28:26 UTC 2006 i686 GNU/Linux
Ноут с AMD Turion64 X2 3200+
компилятор gcc 4.1

hibou ★★★★★
()
Ответ на: комментарий от Deleted

Linux t3x 2.6.19-1.2895.fc6 #1 SMP Wed Jan 10 18:50:56 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

AMD Athlon(tm) 64 Processor 3000+

./solid

500 500 250000 0.79000 0.96000 0.17000 4.1375749E+01 4.1375749E+01

nice -n -20 ./solid 500 500 250000 0.76000 0.91000 0.15000 4.1375749E+01 4.1375749E+01

а че в gnuplot пипиську не нарисовала?

hooj ★★
()
Ответ на: комментарий от hooj

ну нифига себе...

gcc -o solid -O7 -ffast-math -fstrength-reduce -m32 solid-linux.org.ru.c

[t3x@t3x matr-test]$ ./solid 500 500 250000 0.78000 0.84000 0.06000 4.1375749E+01 4.1375749E+01

[t3x@t3x matr-test]$ ./solid 500 500 250000 0.77000 0.85000 0.08000 4.1375749E+01 4.1375749E+01

[t3x@t3x matr-test]$ ./solid 500 500 250000 0.78000 0.85000 0.07000 4.1375749E+01 4.1375749E+01

hooj ★★
()
Ответ на: комментарий от Die-Hard

> model name : Dual-Core AMD Opteron(tm) Processor 2218

У тебя DDR2 и частота - 2.6Ghz, а у меня - DDR и 2.4Ghz. Странно, я думал, что у тебя больше выигрыш будет.

Deleted
()
Ответ на: комментарий от Deleted

Кстати да, писал когда-то тесты на сравнение gcc и icc (был легальный icc в лаборатории). В одних ситуациях один лучше, в других - другой.

pacify ★★★★★
() автор топика
Ответ на: комментарий от Deleted

> В смысле - хочешь сказать, что твой icc хуже, чем мой gcc? ;)

На этой бенчмарке icc на этом Оптероне конкрено сливает!

Версии gcc у нас разные.

Die-Hard ★★★★★
()
Ответ на: комментарий от pacify

Кстати, обратите внимание на приведенные мной результаты для Итаника. Там icc уделывает gcc в три раза!

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Тьфу, блин :) Не туда посмотрел. А ты попробуй более стабильную версию gcc поставить, например, 4.1.х(или 3.4.6) Вроде как 4.0.х - не хочень хороша в плане выдаваемых бинарей.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.