С# vs C++, голые цифры
От: IID Россия  
Дата: 19.05.09 20:30
Оценка: 11 (6) +5 -1 :))
В соселней ветке "Работа — с чего начать: С++ или С#?" было озвучено мнение
Автор: samius
Дата: 19.05.09
, что C# немного медленее С++. И даже предложен код на C#
Автор: IID
Дата: 19.05.09
.

Я привёл код в компилябельное состояние. Вот C# вариант, а вот C++ вариант. Для компиляции использовалась MSVS2008 со всеми обновлениями.
— компилятор C# версии 3.5 Настроки релизной сборки — дефолтные. (Там-то и настраивать особо нечего).
— компилятор Intel С++ 11.0.072. Релизная сборка кастомизирована. Впрочем, разница между дефолтной релизной сборкой и кастомизированной невелика, порядка 10-15%. Ключи компиляции:

/c /O2 /Og /Oi /Ot /Oy /Qipo /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /EHsc /MD /GS- /Gy /fp:fast /Yu"StdAfx.h" /Fp"Release/SpeedTestCpp.pch" /Fo"Release/" /W3 /nologo /Zi /QxSSSE3 /Qparallel /Qprof_use /Qprof_dir "Release"


Тестовая машина: Intel Core2 Q6600, 800mhz RAM 8Gb. ОС — Windows 7 RC1 x64. Программы собирались для x86.
Условия прогона: в диапазонах, указанных автором оригинального C# кода. Шаг по X/Y составляет 0.001 (всего за прогон обсчитывается 9млн пикселей). Делается 100(сто) прогонов подряд. Вычисляется суммарное время.
Побочные эффекты: практически исключены. Сторонней нагрузки не было, taskmgr показывал загрузку только одного ядра во время прогонов. Т.е. гипотеза о том что интел компилер сумел заюзать несколько ядер отпадает.

Результаты:
С#: 2m 14s (134 секунды)
С++: 27 секунд

С++ показал практически пятикратное преимущество (496%), обеспечив обсчёт ~33.33млн пикселей в секунду. C# осилил только ~6.71млн пикселей в секунду. (что довольно близко к результату автора в 5.9млн пикселей)

Итог: подавляющее превосходство С++. Не "немного быстрее", как утверждал автор, а в разы. Причём задача сводилась, фактически, только к грамотному распихиванию FPU команд. Интересно было бы посмотреть на работу с битами. Думаю, тут интел смог бы обеспечить ещё больший отрыв.
kalsarikännit
Re: С# vs C++, голые цифры
От: Alexander G Украина  
Дата: 19.05.09 20:41
Оценка: :))
Здравствуйте, IID, Вы писали:

IID>Причём задача сводилась, фактически, только к грамотному распихиванию FPU команд.


Вот именно. Посмотрим что С++ покажет, если задача будет сводится к поседовательности вызовов new
Re: С# vs C++, голые цифры
От: Antikrot  
Дата: 19.05.09 20:44
Оценка: +2
Здравствуйте, IID, Вы писали:

IID>В соселней ветке "Работа — с чего начать: С++ или С#?" было озвучено мнение
Автор: samius
Дата: 19.05.09
, что C# немного медленее С++. И даже предложен код на C#
Автор: IID
Дата: 19.05.09
.


IID>Я привёл код в компилябельное состояние. Вот C# вариант, а вот C++ вариант. Для компиляции использовалась MSVS2008 со всеми обновлениями.


тест некорректен, результат вызова внутри циклов нигде не используется, компилятор мог там выкинуть что угодно (DCE, фигли, на таком-то уровне оптимизации да еще с проф-юзом), ограничившись парой вызовов time и cout<<

посему надо либо переделать, либо доказывай по асмовому коду что ничего не выкинуто
Re[2]: С# vs C++, голые цифры
От: IID Россия  
Дата: 19.05.09 21:13
Оценка:
Здравствуйте, Antikrot, Вы писали:


A>тест некорректен, результат вызова внутри циклов нигде не используется, компилятор мог там выкинуть что угодно (DCE, фигли, на таком-то уровне оптимизации да еще с проф-юзом), ограничившись парой вызовов time и cout<<


Тогда что он делал 27 секунд ?

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


Я, вообще-то в первоначальном топике так и предлагал — генерировать массивы чисел и проверять их на совпадение. Ок, аргумент уместен. Но это уже завтра.
kalsarikännit
Re[3]: С# vs C++, голые цифры
От: Antikrot  
Дата: 19.05.09 21:15
Оценка:
Здравствуйте, IID, Вы писали:

A>>тест некорректен, результат вызова внутри циклов нигде не используется, компилятор мог там выкинуть что угодно (DCE, фигли, на таком-то уровне оптимизации да еще с проф-юзом), ограничившись парой вызовов time и cout<<

IID>Тогда что он делал 27 секунд ?
ну, возможно, он выкинул *не всё*. но мне сейчас несподручно ставить нужную версию компилятора для проверки
Re[2]: С# vs C++, голые цифры
От: IID Россия  
Дата: 19.05.09 21:21
Оценка: +1
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, IID, Вы писали:


IID>>Причём задача сводилась, фактически, только к грамотному распихиванию FPU команд.


AG>Вот именно. Посмотрим что С++ покажет, если задача будет сводится к поседовательности вызовов new


Давай C# вариант. Перепишем на С++ и поглядим. Есс-но аллокацию памяти я буду использовать такую, какую захочу.
kalsarikännit
Re[3]: С# vs C++, голые цифры
От: Sorantis Швеция sorantis.blogspot.com
Дата: 19.05.09 21:32
Оценка: 1 (1)
Здравствуйте, IID, Вы писали:

Запустил С++ вариант под МС компиллер.
Время показало 3 секунды. ЧЯДНТ?
Время шарпов такое же как у тебя.
As long as there is life, there is hope
Re: С# vs C++, голые цифры
От: criosray  
Дата: 19.05.09 21:43
Оценка: 3 (3) +2 -1
Здравствуйте, IID, Вы писали:

IID>В соселней ветке "Работа — с чего начать: С++ или С#?" было озвучено мнение
Автор: samius
Дата: 19.05.09
, что C# немного медленее С++. И даже предложен код на C#
Автор: IID
Дата: 19.05.09
.


IID>Я привёл код в компилябельное состояние. Вот C# вариант, а вот C++ вариант. Для компиляции использовалась MSVS2008 со всеми обновлениями.

IID>- компилятор C# версии 3.5 Настроки релизной сборки — дефолтные. (Там-то и настраивать особо нечего).
IID>- компилятор Intel С++ 11.0.072. Релизная сборка кастомизирована. Впрочем, разница между дефолтной релизной сборкой и кастомизированной невелика, порядка 10-15%. Ключи компиляции:

Во-первых, Вы понимаете, что это синтетическая числодробилка меряет не более, чем попугайчики?
Во-вторых, почему в С++ варианте у Вас floor, а в С# Math.Round(x,1) ?

Потратив десять минут на оптимизацию этого гения числодробильной мысли получил результат:

Elapsed 00:00:27.2390376 sec.

К сожалению на руках нет Intel С++ компиллятора, чтоб сравнить.

Код:

    class Aux
    {
        public double x, y, z;

        double ZzzFunc()
        {
            double xmy = x - y; 
            
            return xmy - Math.Floor(xmy);
        }
        double Spiral_()
        {
            double xk = x * 20; 
            const double a = 0.2; 
            const double b = 1.5;

            double y1 = y * b - a * Math.Sin(xk);
            double z1 = z * b - a * Math.Cos(xk);
            
            return y1 * y1 + z1 * z1;
        }

        public bool Golova()
        {
            return x < 0.0 && x * x + y * y + z * z < 1.0 && !Shliz();
        }
        
        private bool Spiral()
        {
            return x > 0.0 && x < 1.75 && Math.Abs(Spiral_()) < 0.5;
        }

        private bool Shliz()
        {
            return x < -0.4 && y < 0.1 && y > -0.1;
        }

        private bool Strokes()
        {
            return (Math.Abs(0.5 - x) < 0.02
                    || (x > 0.5 && Math.Abs(ZzzFunc()) < 0.005))
                   && !Spiral() && !Golova();
        }

        private bool Wall()
        {
            return x > 0.5 && !Strokes() && !Spiral();
        }

        public int GetColor()
        {
            if (Golova()) return 1;
            if (Spiral()) return 2;
            if (Strokes()) return 3;
            if (Wall()) return 4;
            return 0;
        }
    };

    class Program
    {
        static void Main(string[] args)
        {
            var a = new Aux();
            
            var stopWatch = new System.Diagnostics.Stopwatch();

            stopWatch.Start();

            Parallel.For(0, 100, i =>
                         {
                             a.z = 0;
                             for (a.y = -1.5; a.y < 1.5; a.y += 0.001)
                             {
                                 for (a.x = -1; a.x < 2; a.x += 0.001)
                                 {
                                     int c = a.GetColor();
                                 }
                             }
                             
                         });

            stopWatch.Stop();

            Console.WriteLine("Elapsed {0} sec.\n", stopWatch.Elapsed);
            Console.ReadKey();
        }


Что поменял:
1) сменил бредовое использование параметров во внутренних методах классов на использование полей класса;
2) заменил Math.Round на Math.Floor
2) самое значимое — так как алгоритм явно элементарно параллелится, то раскидал его на все доступные (их два у меня) ядра процессора с помощью Parallel.For

Вы скажете, что ах ну конечно я тоже мог бы использовать OpenMP и распаралеллить — могли, но не использовали.
Предпологаю, что у меня более быстрый процессор (Core2Duo 3GHz), чем у Вас, и что вариант на С++ отработал бы быстрее, чем за 27 секунд. Да. Но даже если бы он отработал в два раза быстрее (что сомнительно), все-равно мы видим, что "тормозной дотнет" на самом синтетичном и выигрышном для Intel C++ (самого мегаоптимизирующего С++ компиллятора с оптимизациями под Ваш процессор) тесте отстает-то в лучшем случае в два раза, а в худшем — так вообще ноздря в ноздрю.

Вот так "интерпретируемый язык" (с) Шеридан соперничает на числодробильном тесте с Intel C++
Re: С# vs C++, голые цифры
От: Lloyd Россия  
Дата: 19.05.09 21:44
Оценка: :)
Здравствуйте, IID, Вы писали:

IID>Итог: подавляющее превосходство С++. Не "немного быстрее", как утверждал автор, а в разы. Причём задача сводилась, фактически, только к грамотному распихиванию FPU команд. Интересно было бы посмотреть на работу с битами. Думаю, тут интел смог бы обеспечить ещё больший отрыв.


Не "превосходство С++", а превоходство интеловского компилятора перед MS-овским jit-ом.
Для корректного сравнения компилируйте C++-код MS-компилятором и сравнивайте.
Re[2]: С# vs C++, голые цифры
От: Sorantis Швеция sorantis.blogspot.com
Дата: 19.05.09 21:49
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, IID, Вы писали:


IID>>Итог: подавляющее превосходство С++. Не "немного быстрее", как утверждал автор, а в разы. Причём задача сводилась, фактически, только к грамотному распихиванию FPU команд. Интересно было бы посмотреть на работу с битами. Думаю, тут интел смог бы обеспечить ещё больший отрыв.


L>Не "превосходство С++", а превоходство интеловского компилятора перед MS-овским jit-ом.

L>Для корректного сравнения компилируйте C++-код MS-компилятором и сравнивайте.

ну я и говорю.
3 секунды под МС компиллер.
As long as there is life, there is hope
Re[3]: С# vs C++, голые цифры
От: Antikrot  
Дата: 19.05.09 22:03
Оценка:
Здравствуйте, Sorantis, Вы писали:

S>ну я и говорю.

S>3 секунды под МС компиллер.
у меня за 0 секунд
Re: С# vs C++, голые цифры
От: Antikrot  
Дата: 19.05.09 22:04
Оценка:
Здравствуйте, IID, Вы писали:

IID>

IID>/c /O2 /Og /Oi /Ot /Oy /Qipo /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /EHsc /MD /GS- /Gy /fp:fast /Yu"StdAfx.h" /Fp"Release/SpeedTestCpp.pch" /Fo"Release/" /W3 /nologo /Zi /QxSSSE3 /Qparallel /Qprof_use /Qprof_dir "Release"

просто из интереса — замени O2 на O3
Re[3]: С# vs C++, голые цифры
От: midcyber
Дата: 19.05.09 22:06
Оценка:
Здравствуйте, Sorantis, Вы писали:

S>ну я и говорю.

S>3 секунды под МС компиллер.

Дай угадаю — если результат вычислений сохранять куда-либо, например в массив, то будет 60..90 секунд?
Re[2]: С# vs C++, голые цифры
От: Хвост  
Дата: 19.05.09 22:13
Оценка:
Здравствуйте, criosray, Вы писали:

C>2) самое значимое — так как алгоритм явно элементарно параллелится, то раскидал его на все доступные (их два у меня) ядра процессора с помощью Parallel.For

а можно узнать результаты теста без Parallel.For? меня терзают смутные сомнения что вы преувеличили лёгкость распараллеливания алгоритма и он у вас просто некорректно работает.
People write code, programming languages don't.
Re[3]: С# vs C++, голые цифры
От: criosray  
Дата: 19.05.09 22:18
Оценка: +1 -1 :))
Здравствуйте, Sorantis, Вы писали:

L>>Не "превосходство С++", а превоходство интеловского компилятора перед MS-овским jit-ом.

L>>Для корректного сравнения компилируйте C++-код MS-компилятором и сравнивайте.

S>ну я и говорю.

S>3 секунды под МС компиллер.

Потому что он умный и не станет гонять пустой цикл (а цикл пустой, т.к. результат расчетов нигде не используется, о чем, кстати, меня предупреждает среда Visual C#).

Если поменять код вот так, то получаем очень даже замечательный результат


            int x = 0;
            Parallel.For(0, 100, i =>
                         {
                             a.z = 0;
                             for (a.y = -1.5; a.y < 1.5; a.y += 0.001)
                             {
                                 for (a.x = -1; a.x < 2; a.x += 0.001)
                                 {
                                     x += a.GetColor();
                                 }
                             }
                         });

Elapsed 00:00:28.1069964 sec.

    int x = 0;

    for(int i = 0; i < 100; i++)
    {
        a.z = 0;
        for(a.y = -1.5; a.y < 1.5; a.y += 0.001)
        {
            for(a.x = -1; a.x < 2; a.x += 0.001)
            {
                 x += a.GetColor();
            }
        }
    }


elapsed: 77 seconds.

Оба-на! Вот и приехали. Замечательный язык С++ не менее замечательно продул.

Уверен, что результат с OpenMP был бы на уровне шарпового, но проверить не могу — лень возиться и разбираться с OMP.
Re[3]: С# vs C++, голые цифры
От: midcyber
Дата: 19.05.09 22:26
Оценка:
Здравствуйте, Хвост, Вы писали:

Х>Здравствуйте, criosray, Вы писали:


C>>2) самое значимое — так как алгоритм явно элементарно параллелится, то раскидал его на все доступные (их два у меня) ядра процессора с помощью Parallel.For

Х>а можно узнать результаты теста без Parallel.For? меня терзают смутные сомнения что вы преувеличили лёгкость распараллеливания алгоритма и он у вас просто некорректно работает.

Ну если учесть, что C++ алгоритм из примера ВООБЩЕ не работает
Re[4]: С# vs C++, голые цифры
От: Sorantis Швеция sorantis.blogspot.com
Дата: 19.05.09 22:27
Оценка:
Здравствуйте, midcyber, Вы писали:

M>Здравствуйте, Хвост, Вы писали:


Х>>Здравствуйте, criosray, Вы писали:


C>>>2) самое значимое — так как алгоритм явно элементарно параллелится, то раскидал его на все доступные (их два у меня) ядра процессора с помощью Parallel.For

Х>>а можно узнать результаты теста без Parallel.For? меня терзают смутные сомнения что вы преувеличили лёгкость распараллеливания алгоритма и он у вас просто некорректно работает.

M>Ну если учесть, что C++ алгоритм из примера ВООБЩЕ не работает


Вобщем ветка создана потому что уж очень много страниц в предыдущей.
Ложный вызов товарищи
As long as there is life, there is hope
Re[4]: С# vs C++, голые цифры
От: Antikrot  
Дата: 19.05.09 22:34
Оценка:
Здравствуйте, criosray, Вы писали:

C>Оба-на! Вот и приехали. Замечательный язык С++ не менее замечательно продул.

C>Уверен, что результат с OpenMP был бы на уровне шарпового, но проверить не могу — лень возиться и разбираться с OMP.
распечай "х", чтобы убедиться что результат одинаковый. завтра буду уделывать с#
Re[4]: С# vs C++, голые цифры
От: Хвост  
Дата: 19.05.09 22:35
Оценка:
Здравствуйте, midcyber, Вы писали:

M>Ну если учесть, что C++ алгоритм из примера ВООБЩЕ не работает

надеюсь вы находитесь в трезвом уме и твёрдой памяти и понимаете разницу между "алгоритм был изменён человеком так что исключена его корректная работа" и "в целях оптимизации, код алгоритма не был сгенерирован компилятором"
People write code, programming languages don't.
Re[3]: С# vs C++, голые цифры
От: criosray  
Дата: 19.05.09 22:39
Оценка:
Здравствуйте, Хвост, Вы писали:

C>>2) самое значимое — так как алгоритм явно элементарно параллелится, то раскидал его на все доступные (их два у меня) ядра процессора с помощью Parallel.For

Х>а можно узнать результаты теста без Parallel.For? меня терзают смутные сомнения что вы преувеличили лёгкость распараллеливания алгоритма и он у вас просто некорректно работает.

Elapsed 00:01:26.8746531

86 секунд — то есть примерно на 10-12% медлененнее С++ варианта.

На счет Parallel.For Вы правы — работает некорректно. Каюсь, час ночи + спешка — преувеличил легкость распараллеливания.

Завтра на свежую голову посмотрю внимательнее как его распараллелить.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.