LINUX.ORG.RU
ФорумTalks

выбирайте правильно средства под задачу (ответ на тему «g++ sucks»)


0

0

В ответ на тему от Бирдяя на тему меряния пип^W компиляторами.
Меряемся языками. Задача - расчет интеграла от x^2 методом трапеций.

**********************************************************************

Претендент первый - pure C:

[annoynimous@node6 birdie-sucks]$ cat 1Dint.c
#include<stdio.h>
#include<math.h>

#define eps 1e-7

double
square (double x)
{
  return x * x;
};

double
integrate (double a, double b, double (*integrand) (double x))
{
  if (fabs (b - a) < eps)
    {
      return integrand ((a + b) / 2.) * (b - a);
    }
  else
    {
      return (integrate (a, (a + b) / 2., integrand) +
              integrate ((a + b) / 2., b, integrand));
    };
}

int
main (void)
{

  printf ("%18.15f\n", integrate (0., 1., square));
  return 0;

}
[annoynimous@node6 birdie-sucks]$
[annoynimous@node6 birdie-sucks]$ gcc -O2 -ffast-math 1Dint.c -o 1Dint
[annoynimous@node6 birdie-sucks]$ time ./1Dint
 0.333333333333333

real    0m0.617s
user    0m0.534s
sys     0m0.001s
[annoynimous@node6 birdie-sucks]$

**********************************************************************

Претендент второй - Guile:

[annoynimous@node6 birdie-sucks]$ cat 1Dint.lsp
#!/usr/bin/guile -s
!#

(define eps 1e-7)

(define (mid-point a b)
  (/ (+ a b) 2.0))

(define (int a b f)
    (if (< (abs (- b a)) eps)
         (* (f (mid-point a b)) (- b a))
         (+ (int a (mid-point a b) f) (int (mid-point a b) b f))))

(display (int 0. 1. (lambda (x) (* x x))))
(newline)
[annoynimous@node6 birdie-sucks]$
[annoynimous@node6 birdie-sucks]$ time ./1Dint.lsp
0.333333333333333

real    1m19.748s
user    1m13.086s
sys     0m0.117s
[annoynimous@node6 birdie-sucks]$

Получаем, что С быстрее в 129 раз. Вывод делаем сами. :)

ЗЫ. Все совпадения, найденные в тексте - случайны. 
Ответ на: комментарий от zort

> только прикол в том, что сравнивались не разные языки, а разные компиляторы одного языка, поэтому "один и тот же алгоритм на разных языках" это вабще не в тему. Вот если бы ты привёл один и тот же алгоритм, закодированный двумя разными способами, такими что на разных компиляторах эти коды имеют "разницу в производительности в порядки", то это было бы хотя бы в тему.

"В моей песне ты не понял, увы, ничего". Объясняю по-простому: на кой хер сравнивать компиляторы, если простой сменой языка можно получить больше выгоды? Тем более, что сравнение компиляторов никуда не годится. Теем более, что даже нет уверенности, что таймеры в wine реализованы верно и тайминги, выписываемые прогой, реальны.

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

birdit> Я больше здесь ничего писать не буду.

И правильно. Всё равно аргументировать нормально не можешь. Эмулятор... Умник, блин, нашёлся.

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

> Я больше здесь ничего писать не буду.

LOR просто осиротеет :D

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

всё я правильно понял, ведь это твои слова:

>разница вполне может быть обусловлена не качеством компилятора как таковым, а "прослойкой между клавиатурой и стулом", т.е. вкусами и привычками самого программиста.

в посте на который я ответил показан способ с помощью которого это можно подтвердить, правда для того что бы это относилось к 7z, придётся найти тот-же "про-msvc способ кодирования" в исходниках 7z.

унылое говно вроде "если простой сменой языка можно получить больше выгоды" даже не обсуждается, потому что посыл бирди к _выбору_ отношения не имел. Он имел отношение к разнице в производительности компиляторов, а наезд на OSS-комюнити и "предложение g++ или gcc не выбирать а выбирать msvc" нафантазировал уже ты.

>и тайминги, выписываемые прогой, реальны.

ну если выяснится что тайминги не правильные, или в виндовой версии есть asм-вставки которых нет в линуксовой, то конечно получится что предположение бирди не верно, и тема закрыта. Но ты это не выяснил. Ты зачем то сравнил производительность интерпретатора с нативным кодом и начал что то мямлить про выбор....

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

> ну если выяснится что тайминги не правильные, или в виндовой версии есть asм-вставки которых нет в линуксовой, то конечно получится что предположение бирди

> унылое говно

Ага. Согласен.

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

> ничего более вменяемого, кроме cмены порядка слов голову не пришло ?

Так Вы все равно не слышите моих, увы. Остается только шутить.

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

Так о чём спор? Сдался вам этот 7zip. Для чистоты эксперимента надо написать программку. Причём так, что бы она компилилась на обоих компиляторах без изменений. И сравнить время выполнения в обоих случаях. Жалко у меня нет msvc, а так уж давно это проделал бы.

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

когда я не вижу темы "выбора" в теме "сравнения компиляторов", это называется "не слышите моих, увы". Хорошо, так и запишем.

zort
()

Вот флуду-то устроили. Бирди, как обычно, на что-нибудь жалуется в толкс, это не ново. Констатировали факт, значит gcc еще есть куда развиваться.

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

ГЦЦ от версии к версии всё медленнее работает и генерит непонятно что: тупейший баг c inline в scimark2 они уже год не могут пофиксить. По моим личным наблюдениям ГЦЦ гораздо хуже с этим (inline-подстановки) справляется, чем VC7

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

И приведённый пример совсем не в тему сравнения эффективности генерации кода разными компиляторами _одного_ языка программирования. С аргументами вроде "а этот алгоритм сжатия для линукс/виндавс не оптимизирован" - в сад

frame ★★★
()

> Получаем, что С быстрее в 129 раз. Вывод делаем сами. :)

А если вот так:

(define eps 1e-7)

(define log2
  (lambda (x) (/ (log x) (log 2))))

(define (int a b f)
  (let* ((section (abs (- b a)))
         (dx (/ section
                (expt 2
                      (+ (truncate (log2 (/ section
                                            eps))) 1)))))
    (let collect ((result 0.0)
                  (current a))
      (if (>= current b)
          result
          (collect (+ result (* (f current) dx))
                   (+ current dx))))))

(display (int 0. 1. (lambda (x) (* x x))))
(newline)

swizard
()

guile - самая тормозная Схема из всех. Попробуй то же самое, но с bigloo, и расскажи о результате сравнения.

anonymous
()

я конечно глупый, но не понимаю - зачем здесь использовать 
указатель на функцию? 
без указателя на функцию, у меня на машине работает быстрее, 
так в чём прикол? и судя по ассемблерному выводу, разницы 
большой нет, кроме явного вызова функции?

----------integdummy.c
#include<stdio.h>
#include<math.h>

#define eps 1e-7

double
square (double x)
{
  return x * x;
};

double
integrate (double a, double b)
{
  if (fabs (b - a) < eps)
    {
      return square((a + b) / 2.) * (b - a);
    }
  else
    {
      return (integrate (a, (a + b) / 2.) +
              integrate ((a + b) / 2., b));
    };
}

int
main (void)
{

  printf ("%18.15f\n", integrate (0., 1.));
  return 0;

}
----------integdummy.c
gcc integ.c -o integ
time ./integ
 0.333333333333333

real    0m1.730s
user    0m1.693s
sys     0m0.003s

integ.c - оригинальный файл
gcc -O2 -ffast-math integ.c -o integO2
time ./integO2
 0.333333333333333

real    0m0.552s
user    0m0.530s
sys     0m0.004s

gcc -o integdummy integdummy.c
time ./integdummy
 0.333333333333333

real    0m1.675s
user    0m1.631s
sys     0m0.003s

gcc -O2 -ffast-math integdummy.c -o integdummyO2
time ./integdummyO2
 0.333333333333333

real    0m0.541s
user    0m0.512s
sys     0m0.003s

вот можете ещё свою jvm потестить :)
----------integdummy.java
public class integdummy {
        static double eps = 1e-7;
        static double integrate(double a, double b){
                if ( Math.abs(a - b) < eps) {
                        return( Math.pow( (a +b)/ 2d, 2d ) * (b - a) );
                }else{
                        return( integrate(a, (a + b) / 2d )
                        + integrate((a + b)/ 2d, b) );
                }
        }
        public static void main(String[] args){
                System.out.println( integrate( 0d, 1d ) );
        }
}
----------integdummy.java
javac integdummy.java
time java integdummy
0.33333333333333304

real    0m28.515s
user    0m28.033s
sys     0m0.053s
java --version
java version "1.5.0"
gij (GNU libgcj) version 4.1.2 20070502 (Red Hat 4.1.2-12)

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

вот ещё diff асемблера:

diff integ.asm integdummy.asm
1c1
<       .file   "integ.c"
---
>       .file   "integdummy.c"
33c33
<       subl    $56, %esp
---
>       subl    $48, %esp
57,58c57
<       movl    24(%ebp), %eax
<       call    *%eax
---
>       call    square
69,70d67
<       movl    24(%ebp), %eax
<       movl    %eax, 16(%esp)
80,81d76
<       movl    24(%ebp), %eax
<       movl    %eax, 16(%esp)
108d102
<       movl    $square, 16(%esp)

anonymous
()

> Получаем, что С быстрее в 129 раз. Вывод делаем сами.

Btw скомпилируй свою схемовскую прогу сталином -- http://en.wikipedia.org/wiki/Stalin_(Scheme_implementation)

У меня отставание от Си-варианта (при -O3) получилось только в 1.9 раз :)

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

> я конечно глупый, но не понимаю - зачем здесь использовать указатель на функцию?

Затем, что алгоритм интегрирования не зависит (в очень широких предположениях) от интегрируемой функции. Представьте, что Вы интегрируете функцию, которая написана не Вами и находится в скомпилированном объектном файле, а исходного текста нет.

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

А, понял, что Вы имеете в виду. Ну да, вычисление фактически происходит в момент, когда длина интервала не превосходит epsilon, и аргумент - указатель на функцию - можно, конечно, не тянуть за собой на стеке. Однако он все равно нужен, если выполнены условия предыдущего поста.

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