Re[36]: C# - from indians by indians
От: alex_public  
Дата: 08.06.15 00:19
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Конечно в первую очередь это инструмент для портирования, причём успешный (Unreal Engine портировали за 4 дня, уже портированно QT и т.п.).


Хм, Qt на JS? ) Интересно взглянуть на использование подобного инструмента. ) Особенно если учесть то, какие бинарники генерирует Qt.

EP>Странно: GCC завекторизировал исходную форму, но только в x32 (на Coliru по умолчанию было x64).


У меня тоже gcc (4.9.1). Разницы в 64/32 можно сказать нет. На C# аналогично. На Java пробовал только х64 вариант. )
Re[32]: C# - from indians by indians
От: Aртём Австралия жж
Дата: 08.06.15 03:15
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Этот феерический бред сгененировал кажется тот же самый персонаж, что заявлял, что на микроконтроллерах нет C++? И который предлагал оценивать быстродействие Питона по numpy и быстройдействие Java по blas/lapack? Может стоит просто забанить его на форуме? Понятно же ведь, что это или сверхжирный тролль или школьник.


Вот и религиозный C++"поклонник"отметился
Re[37]: C# - from indians by indians
От: Evgeny.Panasyuk Россия  
Дата: 08.06.15 09:42
Оценка: 6 (4)
Здравствуйте, alex_public, Вы писали:

EP>>Конечно в первую очередь это инструмент для портирования, причём успешный (Unreal Engine портировали за 4 дня, уже портированно QT и т.п.).

_>Хм, Qt на JS? ) Интересно взглянуть на использование подобного инструмента. ) Особенно если учесть то, какие бинарники генерирует Qt.

Ага, сам удивился когда узнал.
Вот тут живые примеры QT. Тут интерпретатор Python внутри JS. На JS даже Clang портировали. Общий список демок.

EP>>Странно: GCC завекторизировал исходную форму, но только в x32 (на Coliru по умолчанию было x64).

_>У меня тоже gcc (4.9.1). Разницы в 64/32 можно сказать нет.

У тебя код другой. Я же говорю про исходный — он векторизируется GCC, но только в x32.
Re[38]: C# - from indians by indians
От: Aртём Австралия жж
Дата: 08.06.15 12:22
Оценка: +1 -1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Вот тут живые примеры QT. Тут интерпретатор Python внутри JS. На JS даже Clang портировали. Общий список демок.


  Можно, но зачем?
Re[39]: C# - from indians by indians
От: Evgeny.Panasyuk Россия  
Дата: 08.06.15 12:38
Оценка: 3 (2) +1
Здравствуйте, Aртём, Вы писали:

EP>>Вот тут живые примеры QT. Тут интерпретатор Python внутри JS. На JS даже Clang портировали. Общий список демок.

Aё>Можно, но зачем?

Портирование Clang, Python и QT — это скорее демонстрация того что Emscripten справляется с большими проектами. Но это же не единственные примеры.
http://www.youtube.com/watch?v=BV32Cs_CMqo
Re[15]: C# - from indians by indians
От: Sinix  
Дата: 08.06.15 13:14
Оценка:
Здравствуйте, alex_public, Вы писали:

_>P.S. C# версия (без фокусов с fixed, которые превращают C# в кривой аналог C) работает в 7 раз медленнее C++ кода.

Не для спора

А можно весь код на шарпе, чисто посмотреть, что там не так?

Ну и плюсовый, чтоб сравнить.
Re[33]: C# - from indians by indians
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.06.15 14:10
Оценка: 1 (1) -1 :)
Здравствуйте, greenpci, Вы писали:


G>В реальных корпоративных условиях эта иллюзия экономии может стоить компаниям очень дорого. Во первых, в дотнете есть технические и не технические специалисты. Дотнет фильтрует людей гораздо хуже, чем плюсы. Там легче имитировать опыт и показаться работодателю программистом, на самом деле таковым не являясь. Вероятность, что ты наймешь действительно технического профессионала, который любит свою работу, будет выше на плюсах. А когда что-то любишь делать, работа кипит и заказчик доволен. Другими словами, си плюс плюс программист, который любит свою работу, напишет код быстрее и лучше, за счет энтузиазма, чем дотнетчик, который ее не любит.

А ты хоть раз людей собеседовал? Сказки какие-то рассказываешь. У меня есть 10 вопросов, которые точно показывают насколько человек понимает .NET. Программисты с 5+ годами опыта отвечают в среднем на 7. Так что с фильтрацией пробел никаких нет. А что касается вероятности нахождения профессионала, то она тем выше, чем больше рынок. На узком рынке вообще сложно что-то найти.
Твое мнение построено на незнании.



G>>имеет никакого смысла и верно только в контексте фейсбука\гугла и еще пары-тройки гигантов. В остальных случаях сложность оптимизации на C++ и C# (и иногда Java) сравнимы, а учитывая в общем более высокую сложность разработки на C++ еще непонятно что будет проще в итоге.

G>Разработка на плюсах имеет некоторую сложность, но эта сложность преувеличена. Программист, работающий на плюсах много лет, будет достаточно эффективен и не будет дороже стоить.
Наоборот, я бы сказал что эта сложность приуменьшена. Я вот помню случай на 5 курсе универа. Надо было численные методы считать. У нас в группе осталось 8 человек, половина из которых кодила на С++, а я три месяца как начал работать на C#. Так вот была банальная задача с матрицами. Пока C++ программисты писали умножение и вычисление обратных матриц на C++ я успел не только закодить всю математику, но и сделал визуализацию на WinForms. При этом они все лучше знали C++, чем я C#, да еще и опыта имели больше.
Re[35]: C# - from indians by indians
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.06.15 14:22
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


EP>>>Тезис в цитате (с которым я полностью согласен) довольно прост — на C++ проще создать быстрый код. Ты же пытаешься передёрнуть в какую-то совершенно другую плоскость

G>>Плоскость та же самая. Просто ответь на вопрос насколько проще
EP>Намного проще.
Намного это насколько?

G>>и насколько нужна скорость с учетом всех факторов,

EP>Где-то нужна, а где-то нет
Где нужна?

G>>>>Для большинства проектов проценты прироста быстродействия

EP>>>Причём тут "проценты"?
EP>>>Выше как раз показано что при использовании Java-style это не проценты, а разы, и даже порядки.
G>>А при использовании C# не разы.
EP>В разы, бывает и на порядки
Я, слава богу, на java не пишу, а в .net проблем таких не наблюдал. Да и вырожденный во многом случай рассмотрен выше. Мне, например, за все время разработки на .NET понадобились структуры всего пару раз. Я уверен что ту же пару раз спокойно покрывает HotSpot.

G>>Кроме того операции с complex не такой уж частый случай. Я вот сомневаюсь что в том же ФБ много кода, работающего с вещественными числами.

EP>Повторюсь в N-ый раз Это бьёт далеко не только по арифметике и подобным вычислениям.
Ок, покажи другой пример, близкий к реальности, где нет арифметики с комплексными числами, матрицами итп.

G>>>>останутся незамеченными и дешевле будет сделать апгрейд железа, чем заниматься оптимизацией. Поэтому утверждение что "на C++ быстрый код получить на порядки проще" не имеет никакого смысла и верно только в контексте фейсбука\гугла и еще пары-тройки гигантов.

EP>>>Ты почему-то говоришь в контексте каких-то отдельных областей типа web'а — причём так, что как-будто ничего другого нет. Уж по верь "быстрый код на C++" нужен не только гигантам.
G>>Не видел ни одного случая, чтобы без C++ нельзя было добиться достаточного быстродействия.
EP>Опять 25. Без C++, на Java и C# можно добиться быстродействия, что не ясно-то? Ты с чем споришь?
С выделенным.

EP>>>Тебе попадаются задачи где не нужен? Поздравляю, вот только не надо необоснованно экстраполировать свой опыт на всю индустрию.

G>>Как раз ты пытаешься опыт ФБ экстраполировать на всю индустрию.
EP>Где я это пытаюсь делать?
В последних трех постах.

G>>Увы никто, из тех кто будет читать этот форум, даже близко не подойдет к таким масштабам.

EP>Да причём тут вообще масштабы? Есть много программ которые работают на устройствах конечных пользователей и где нужна скорость.
И там почему-то JavaScript, C#, Java и swift. У конечных пользователей скорость очень редко упирается в скорость вычислений.

EP>Ты же пытаешься всё свести к каким-то случаям типа веб-масштабирования. Не хватает только коронного "всё в базу упирается".

Нет, не пытаюсь.

G>>>>В остальных случаях сложность оптимизации на C++ и C# (и иногда Java) сравнимы, а учитывая в общем более высокую сложность разработки на C++ еще непонятно что будет проще в итоге.

EP>>>Нет, не сравнимы. В C++ я могу сделать много уровней абстракций, которые будут либо бесплатными, либо крайне дешёвыми. В C#, а тем более Java, так не получится. И вот за счёт этого получается проще.
G>>А не делать уровни абстракции не? Или ты считаешь, что это на порядок сложнее?

EP>Да, это на порядок сложнее. Например примеры из этого топика:

EP>Вместо того чтобы просто объявить класс Complex — будешь вручную нарезать массив double.
EP>Вместо того чтобы взять готовую ФВП transform, и передать в неё лямбду — будешь выписывать ручной for-цикл.
EP>И чем больше уровней, тем больше ad-hoc boilerplate, причём комбинаторно.
Но это, как мы выяснили уже, вырожденный пример. В реальности не встречающийся. В реальности количество боилерплйта на C++ оказывается не меньше, чем на java или C#.

EP>>>Мой поинт наоборот противоположный, и я уже устал его повторять:

EP>>>Предел оптимизации везде примерно одинаковый, разница в десятки процентов это не так уж серьёзно. Но на C++ этот предел гораздо проще достичь.
G>>На практике ровно наоборот.
EP>Почему это? Вот в этом топике и Java и C# показали скорость близкую к C++.
Потому что быстродействие программ вовсе не от быстродействия математики зависит.

G>>В C++ можно вовсе не выделять память под объекты, а в C#\Java без этого никак. В некоторых случаях только один этот факт позволяет из кода на C++ выжать в разы больше быстродействия. Правда затраты на такую оптимизацию очень быстро превышают разумные пределы.


EP>Ты как раз подтверждаешь мои слова выше. Ты читал на что отвечаешь?

EP>

EP>>>Предел оптимизации везде примерно одинаковый, разница в десятки процентов это не так уж серьёзно. Но на C++ этот предел гораздо проще достичь.
G>>На практике ровно наоборот.

Нет, ты говоришь о другом. Ты говоришь что на C++ проще получить быстрый код. Я говорю что на C++ в любом случае писать сложно, но код можно получить более быстрый, чем с другими языками.
И тогда встает вопрос оправданности использования C++ даже для performance-crtitical расчетов.
Re[34]: C# - from indians by indians
От: Sinix  
Дата: 08.06.15 14:34
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>А ты хоть раз людей собеседовал? Сказки какие-то рассказываешь. У меня есть 10 вопросов, которые точно показывают насколько человек понимает .NET. Программисты с 5+ годами опыта отвечают в среднем на 7.


Да ладно, что там в базовых вещах может быть такого, чтоб с 5 годами опыта не ответить?

Или речь идёт про нюансы конкретных частей фреймворка / перегрузки / этюды в стиле Никова? Там да, до бесконечности валить можно.
Навскидку — раз, Целый ворох — два.

G>Так что с фильтрацией пробел никаких нет.

Угу. Причём для людей с опытом это делается ещё проще — берём любую из статей по сабжу типа такой и просим прокомментировать. Тут заучивание не помогает от слова совсем.
Re[40]: C# - from indians by indians
От: Aртём Австралия жж
Дата: 08.06.15 14:59
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Портирование Clang, Python и QT — это скорее демонстрация того что Emscripten справляется с большими проектами. Но это же не единственные примеры.

EP>http://www.youtube.com/watch?v=BV32Cs_CMqo
Это уже серьёзная заявка. Но какие случаи использования компилятора из C++ в JS ты видишь, где он мог бы быть больше, чем игрушечным проектом "just for fun"? Портировать линейную алгебру на JS, под Node.JS? Но разрабатывать новый код на C++ сложнее, а в уже написанном и оптимизированном мы рискуем потерять в производительности. Вызывать нативный код из Node.JS проблемы не представляет.
Re[36]: C# - from indians by indians
От: Evgeny.Panasyuk Россия  
Дата: 08.06.15 15:32
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>>>Тезис в цитате (с которым я полностью согласен) довольно прост — на C++ проще создать быстрый код. Ты же пытаешься передёрнуть в какую-то совершенно другую плоскость

G>>>Плоскость та же самая. Просто ответь на вопрос насколько проще
EP>>Намного проще.
G>Намного это насколько?

Настолько, что даже в рассматриваемом примере, при использовании удобных средств типа ФВП и лямбд, C++ код скомпилированный в JS (!) оказывается практически в два раза быстрее чем аналогичный на C#.
И это на C# с использованием структур, которые как ты сам пишешь используют редко (а в C++ value type это default) — если же перейти к классам, то там уже получаются отставания на порядки.

G>>>Кроме того операции с complex не такой уж частый случай. Я вот сомневаюсь что в том же ФБ много кода, работающего с вещественными числами.

EP>>Повторюсь в N-ый раз Это бьёт далеко не только по арифметике и подобным вычислениям.
G>Ок, покажи другой пример, близкий к реальности, где нет арифметики с комплексными числами, матрицами итп.

Например послушай какие оптимизации делали вот тут (хотя бы первые полчаса), и почему.
Или тебе нужен короткий пример который мы тут сможем воспроизвести?

EP>>>>Ты почему-то говоришь в контексте каких-то отдельных областей типа web'а — причём так, что как-будто ничего другого нет. Уж по верь "быстрый код на C++" нужен не только гигантам.

G>>>Не видел ни одного случая, чтобы без C++ нельзя было добиться достаточного быстродействия.
EP>>Опять 25. Без C++, на Java и C# можно добиться быстродействия, что не ясно-то? Ты с чем споришь?
G>С выделенным.

А какие у тебя аргументы? И контраргументы какого типа ты сможешь принять?

EP>>>>Тебе попадаются задачи где не нужен? Поздравляю, вот только не надо необоснованно экстраполировать свой опыт на всю индустрию.

G>>>Как раз ты пытаешься опыт ФБ экстраполировать на всю индустрию.
EP>>Где я это пытаюсь делать?
G>В последних трех постах.

Ты прочитай ещё раз цитату. Они не говорят ничего про жёсткие (и дорогие в реализации) оптимизации, хотя и они у них есть. Они говорят что нормально написанный код C++ просто работает быстро, в отличии от Java и т.п.
Примеры в этом топике это также подтверждают — нравится тебе это или нет.

G>>>Увы никто, из тех кто будет читать этот форум, даже близко не подойдет к таким масштабам.

EP>>Да причём тут вообще масштабы? Есть много программ которые работают на устройствах конечных пользователей и где нужна скорость.
G>И там почему-то JavaScript, C#, Java и swift.

Ага. И, барабанная дробь, C++.

EP>>Да, это на порядок сложнее. Например примеры из этого топика:

EP>>Вместо того чтобы просто объявить класс Complex — будешь вручную нарезать массив double.
EP>>Вместо того чтобы взять готовую ФВП transform, и передать в неё лямбду — будешь выписывать ручной for-цикл.
EP>>И чем больше уровней, тем больше ad-hoc boilerplate, причём комбинаторно.
G>Но это, как мы выяснили уже, вырожденный пример. В реальности не встречающийся.

Кто и где это выяснил?

G>В реальности количество боилерплйта на C++ оказывается не меньше, чем на java или C#.


Аргументы?

EP>>>>Мой поинт наоборот противоположный, и я уже устал его повторять:

EP>>>>Предел оптимизации везде примерно одинаковый, разница в десятки процентов это не так уж серьёзно. Но на C++ этот предел гораздо проще достичь.
G>>>На практике ровно наоборот.
EP>>Почему это? Вот в этом топике и Java и C# показали скорость близкую к C++.
G>Потому что быстродействие программ вовсе не от быстродействия математики зависит.

Ты не смотри то что там комплексные числа умножаются — C# код с классами получился медленней практически на два порядка. Даже если бы сами вычисления там были моментальными — то картину это бы никак не поменяло.

G>Ты говоришь что на C++ проще получить быстрый код.


Ну да: "Reasonably written C++ code just runs fast".

G>Я говорю что на C++ в любом случае писать сложно, но код можно получить более быстрый, чем с другими языками.


Прочитай ещё раз цитату:

"The going word at Facebook is that 'reasonably written C++ code just runs fast,' which underscores the enormous effort spent at optimizing PHP and Java code. Paradoxically, C++ code is more difficult to write than in other languages, but efficient code is a lot easier [to write in C++ than in other languages]." – Herb Sutter at //build/, quoting Andrei Alexandrescu

И прочитай выделенное. А потом чётко сформулируй с чем ты не согласен в этой цитате.
Re[41]: C# - from indians by indians
От: Evgeny.Panasyuk Россия  
Дата: 08.06.15 16:23
Оценка:
Здравствуйте, Aртём, Вы писали:

EP>>Портирование Clang, Python и QT — это скорее демонстрация того что Emscripten справляется с большими проектами. Но это же не единственные примеры.

EP>>http://www.youtube.com/watch?v=BV32Cs_CMqo
Aё>Это уже серьёзная заявка. Но какие случаи использования компилятора из C++ в JS ты видишь, где он мог бы быть больше, чем игрушечным проектом "just for fun"?

Игры или например CAD приложения это вполне реальные проекты, а не только "just for fun". Конкретный пример:
http://www.youtube.com/watch?v=1e7fknGX_uQ

Aё>Портировать линейную алгебру на JS, под Node.JS?


Можно портировать любую готовую библиотеку, из любой области, а не создавать новую.

Aё>Вызывать нативный код из Node.JS проблемы не представляет.


Из браузера native код не вызовешь.
Re[35]: C# - from indians by indians
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.06.15 20:35
Оценка: 2 (1) :)
Здравствуйте, Sinix, Вы писали:

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


G>>А ты хоть раз людей собеседовал? Сказки какие-то рассказываешь. У меня есть 10 вопросов, которые точно показывают насколько человек понимает .NET. Программисты с 5+ годами опыта отвечают в среднем на 7.


S>Да ладно, что там в базовых вещах может быть такого, чтоб с 5 годами опыта не ответить?

Большая часть сыпется на value-type vs reference type и боксинге. Очень многие не понимают IDisposable. У некоторых проблемы с IEumerable и yield. А самое удивительное, что все подряд пользуются Linq2SQL\EF еще что-то при этом 10% даже не слышали про expression tree.
Re[16]: C# - from indians by indians
От: alex_public  
Дата: 08.06.15 22:05
Оценка: 5 (2)
Здравствуйте, Sinix, Вы писали:

S>А можно весь код на шарпе, чисто посмотреть, что там не так?

    static long Test()
    {
        var sw = Stopwatch.StartNew();
        var buf=(int[])image.Clone();
        int width=image.Length/height;
        for(int n=0; n<count; n++){
            for(int y=1; y<height-1; y++){
                var p=width*y;
                for(int x=1; x<width-1; x++) if(image[p+x]!=0xffffff)
                    buf[p+x]=(image[p-width+x]+image[p+x-1]+image[p-width+x-1]+image[p-width+x+1]+image[p+width+x-1]+image[p+width+x]+image[p+x+1]+image[p+width+x+1])>>3;
            }
            for(int y=1; y<height-1; y++){
                var p=width*y;
                for(int x=1; x<width-1; x++) if(buf[p+x]!=0xffffff)
                    image[p+x]=(buf[p-width+x]+buf[p+x-1]+buf[p-width+x-1]+buf[p-width+x+1]+buf[p+width+x-1]+buf[p+width+x]+buf[p+x+1]+buf[p+width+x+1])>>3;
            }
        }
        sw.Stop();
        return sw.ElapsedMilliseconds;
    }


S>Ну и плюсовый, чтоб сравнить.

int Test()
{
    cpu_timer timer;
    auto buf=image;
    const int width=image.size()/height;
    for(int n=0; n<count; n++){
        for(int y=1; y<height-1; y++){
            const auto s=image.data()+y*width;
            const auto d=buf.data()+y*width;
            for(int x=1; x<width-1; x++) if(s[x]!=0xffffff)
                d[x]=(s[-width+x]+s[x-1]+s[-width+x-1]+s[-width+x+1]+s[width+x-1]+s[width+x]+s[x+1]+s[width+x+1])>>3;
        }
        for(int y=1; y<height-1; y++){
            const auto s=buf.data()+y*width;
            const auto d=image.data()+y*width;
            for(int x=1; x<width-1; x++) if(s[x]!=0xffffff)
                d[x]=(s[-width+x]+s[x-1]+s[-width+x-1]+s[-width+x+1]+s[width+x-1]+s[width+x]+s[x+1]+s[width+x+1])>>3;
        }
    }
    return timer.elapsed().wall/1000000;
}


P.S. Естественно повторяющийся код можно было бы вынести в отдельную функцию (а особенно в C++ с его инлайном), но в разных языках (кстати тестировались не только C++/java/C#) с этим есть разные нюансы, так что для чистоты эксперимента везде оставлен одинаковый код в лоб.
Re[17]: C# - from indians by indians
От: Sinix  
Дата: 09.06.15 09:29
Оценка: 4 (2)
Здравствуйте, alex_public, Вы писали:


_>P.S. Естественно повторяющийся код можно было бы вынести в отдельную функцию (а особенно в C++ с его инлайном), но в разных языках (кстати тестировались не только C++/java/C#) с этим есть разные нюансы, так что для чистоты эксперимента везде оставлен одинаковый код в лоб.

C# версия (без фокусов с fixed, которые превращают C# в кривой аналог C) работает в 7 раз медленнее C++ кода.

В общем никаких 7 раз у меня нет. Что легко можно списать на моё незнание плюсов (что знал — успешно забыл)

1920*1080, 500 повторов, массив заполнен
image[i] = i % 321;

для проверки берём image[2000], чтоб не поломать ничего.

Для шарпа:
// x64
fast:  5744 ms,  res 256
orig: 10338 ms,  res 256

// x86
fast:  7422 ms,  res 256
orig: 13758 ms,  res 256


fast — просто перевёл на fixed()

Для плюсов (win32)
Run: 6586 ms, res:  256


VS 2013, со всеми обновлениями, релиз, без отладчика, настройки сборки для плюсов по умолчанию.
Кто померяет яву? Подозреваю, там тоже не 5 раз будет.

  код
код шарпа:
    static long Test(int[] image, int height, int count)
    {
        var sw = Stopwatch.StartNew();
        var buf=(int[])image.Clone();
        int width=image.Length/height;
        for(int n=0; n<count; n++){
            for(int y=1; y<height-1; y++){
                var p=width*y;
                for(int x=1; x<width-1; x++) if(image[p+x]!=0xffffff)
                    buf[p+x]=(image[p-width+x]+image[p+x-1]+image[p-width+x-1]+image[p-width+x+1]+image[p+width+x-1]+image[p+width+x]+image[p+x+1]+image[p+width+x+1])>>3;
            }
            for(int y=1; y<height-1; y++){
                var p=width*y;
                for(int x=1; x<width-1; x++) if(buf[p+x]!=0xffffff)
                    image[p+x]=(buf[p-width+x]+buf[p+x-1]+buf[p-width+x-1]+buf[p-width+x+1]+buf[p+width+x-1]+buf[p+width+x]+buf[p+x+1]+buf[p+width+x+1])>>3;
            }
        }
        sw.Stop();
        return sw.ElapsedMilliseconds;
    }

    static long Test2(int[] image, int height, int count)
    {
        var sw = Stopwatch.StartNew();
        var buf = (int[])image.Clone();

        for (int n = 0; n < count; n++)
        {
            AtoB(image, buf, height);
            AtoB(buf, image, height);
        }

        sw.Stop();
        return sw.ElapsedMilliseconds;
    }

    unsafe static void AtoB(int[] image, int[] buf, int height)
    {
        int width = image.Length / height;
        fixed (int* a = image, b = buf)
        {
            for (int y = 1; y < height - 1; y++)
            {
                var p = width * y;
                for (int x = 1; x < width - 1; x++)
                {
                    var idx = a + p + x;
                    var idx2 = b + p + x;
                    if (*idx != 0xffffff)
                    {
                        *idx2 = (
                            *(idx - width) + *(idx - 1) +
                            *(idx - width - 1) + *(idx - width + 1) +
                            *(idx + width - 1) + *(idx + width) +
                            *(idx + 1) + *(idx + width + 1)) >> 3;
                    }
                }
            }
        }
    }

    static void Main()
    {
        int[] image = new int[1920 * 1080];
        var rnd = new Random(0);
        for (int i = 0; i < image.Length; i++)
        {
            image[i] = i % 321;
        }
        int[] image2 = (int[])image.Clone();

        Console.WriteLine("Begin");
        long t;
        t = Test2(image, 1920, 500);
        Console.WriteLine("fast: {0} ms,\tres {1}", t, image[2000]);
        t = Test(image2, 1920, 500);
        Console.WriteLine("orig: {0} ms,\tres {1}", t, image2[2000]);

        Console.Write("Done.");
        Console.ReadKey();
    }


Для плюсов (да, он меня самого заставляет плакать кговавыми слезами):
int main()
{
    const int size = 1920 * 1080;
    const int height = 1920;
    const int count = 500;
    int* image = new int[size];
    for (int i1 = 0; i1 < size; i1++)
    {
        image[i1] = i1 % 321;
    }

    LARGE_INTEGER frequency;
    LARGE_INTEGER t1, t2;
    QueryPerformanceFrequency(&frequency);
    QueryPerformanceCounter(&t1);

    auto buf = image;
    const int width = size / height;
    for (int n = 0; n<count; n++){
        for (int y = 1; y<height - 1; y++){
            const auto s = image + y*width;
            const auto d = buf + y*width;
            for (int x = 1; x<width - 1; x++) if (s[x] != 0xffffff)
                d[x] = (s[-width + x] + s[x - 1] + s[-width + x - 1] + s[-width + x + 1] + s[width + x - 1] + s[width + x] + s[x + 1] + s[width + x + 1]) >> 3;
        }
        for (int y = 1; y<height - 1; y++){
            const auto s = buf + y*width;
            const auto d = image + y*width;
            for (int x = 1; x<width - 1; x++) if (s[x] != 0xffffff)
                d[x] = (s[-width + x] + s[x - 1] + s[-width + x - 1] + s[-width + x + 1] + s[width + x - 1] + s[width + x] + s[x + 1] + s[width + x + 1]) >> 3;
        }
    }
    QueryPerformanceCounter(&t2);
    std::cout << "Run: " << (int)((t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart) << " res:  " << buf[2000];

    delete[] image;
    return 0;
}
Отредактировано 09.06.2015 9:31 Sinix . Предыдущая версия .
Re[16]: C# - from indians by indians
От: Sinix  
Дата: 09.06.15 09:38
Оценка: 1 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

_>>А то он что-то работает в 5 (!) раз медленнее C++ аналога.

_>>P.S. C# версия (без фокусов с fixed, которые превращают C# в кривой аналог C) работает в 7 раз медленнее C++ кода.

EP>А ты сравнивал генерируемый ASM? Как сильно отличается? Точнее в чём там главный тормоз?

У меня такого разброса не получается.
Автор: Sinix
Дата: 09.06.15
Re[36]: C# - from indians by indians
От: Yoriсk  
Дата: 09.06.15 09:42
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>Да ладно, что там в базовых вещах может быть такого, чтоб с 5 годами опыта не ответить?

G>Большая часть сыпется на value-type vs reference type и боксинге. Очень многие не понимают IDisposable. У некоторых проблемы с IEumerable и yield. А самое удивительное, что все подряд пользуются Linq2SQL\EF еще что-то при этом 10% даже не слышали про expression tree.

Что-то без конкретных примеров вопросов и предполагаемых ответов не совсем понятно о чём идёт речь.
Re[18]: C# - from indians by indians
От: alex_public  
Дата: 09.06.15 09:58
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>В общем никаких 7 раз у меня нет. Что легко можно списать на моё незнание плюсов (что знал — успешно забыл)


S>Для шарпа:

S>
S>// x64
S>fast:  5744 ms,  res 256
S>orig: 10338 ms,  res 256

S>// x86
S>fast:  7422 ms,  res 256
S>orig: 13758 ms,  res 256
S>


S>fast — просто перевёл на fixed()


S>Для плюсов (win32)

S>
S>Run: 6586 ms, res:  256
S>


S>VS 2013, со всеми обновлениями, релиз, без отладчика, настройки сборки для плюсов по умолчанию.

S>Кто померяет яву? Подозреваю, там тоже не 5 раз будет.

Скорее всего дело в неверных настройках компилятора C++ — ему не позволена автовекторизация. ) У меня такие цифры (правда компилятор gcc):
C# — 8,7 c
Java = 7,3 с
C++ — 1,3 с.

Однако даже и без автовекторизазии на твоих же цифрах видно, что разница между C++ и C# вариантом в 2 раза — это уже убойно. )))
Re[19]: C# - from indians by indians
От: Sinix  
Дата: 09.06.15 10:18
Оценка: 1 (1)
Здравствуйте, alex_public, Вы писали:

_>Скорее всего дело в неверных настройках компилятора C++ — ему не позволена автовекторизация. ) У меня такие цифры (правда компилятор gcc):

Да, с /Qvec-report:2 вывод:
info C5002: loop not vectorized due to reason '1200'
// Loop contains loop-carried data dependences

Выше по ветке уже был похожий пример
Автор: PM
Дата: 05.06.15
. Компилятор c++ в vs2013 местами не блещет.

_>Однако даже и без автовекторизазии на твоих же цифрах видно, что разница между C++ и C# вариантом в 2 раза — это уже убойно. )))

Угу, нынешний JIT на числомолотилки не заточен, это давно известно. Чисто ради интереса: какой фреймворк и x64 или x86 вариант проверялся?

P.S. Разница в 2 раза там из-за проверок на границы массива. Для всего кроме "i=0;i<array.Length" они не убираются.

UPD Не из-за них, протупил. Для варианта с указателями на 7 сложений меньше, т.к. аналог (a[p + x]) вычисляется 1 раз. Вот этот вариант с указателями, но с доступом по индексу не отличается от safe-варианта:
    unsafe static void AtoB(int[] image, int[] buf, int height)
    {
        int width = image.Length / height;
        fixed (int* a = image, b = buf)
        {
            for (int y = 1; y < height - 1; y++)
            {
                var p = width * y;
                for (int x = 1; x < width - 1; x++)
                {
                    var idx = p + x;
                    if (a[idx] != 0xffffff)
                    {
                        b[idx] = (
                            a[idx - width] + a[idx - 1] +
                            a[idx - width - 1] + a[idx - width + 1] +
                            a[idx + width - 1] + a[idx + width] +
                            a[idx + 1] + a[idx + width + 1]) >> 3;
                    }
                }
            }
        }
    }


UPD2 Ну да, собственно этим твои варианты под шарп и c++ и отличаются
image[p-width+x] // c#
vs
s[-width+x]    // c++, s == image + p

Как только я их привёл к одному виду на автомате — время совпало с нативным результатом без автовекторизации.

Ручную векторизацию конечно можно попробовать сделать с RyuJIT + SIMD, но это уже за гранью добра и зла имхо. Нужна производительность — проще вытащить кусок в unmanaged-код и не страдать из-за "если добавить 7 лишних сложений, то шарп медленный".
Отредактировано 09.06.2015 11:23 Sinix . Предыдущая версия . Еще …
Отредактировано 09.06.2015 11:11 Sinix . Предыдущая версия .
Отредактировано 09.06.2015 10:27 Sinix . Предыдущая версия .
Re[17]: C# - from indians by indians
От: Evgeny.Panasyuk Россия  
Дата: 09.06.15 10:18
Оценка:
Здравствуйте, alex_public, Вы писали:

S>>Ну и плюсовый, чтоб сравнить.

_>
_>int Test()
_>{
_>    cpu_timer timer;
_>    auto buf=image;
_>    const int width=image.size()/height;
_>    for(int n=0; n<count; n++){
_>        for(int y=1; y<height-1; y++){
_>            const auto s=image.data()+y*width;
_>            const auto d=buf.data()+y*width;
_>            for(int x=1; x<width-1; x++) if(s[x]!=0xffffff)
_>                d[x]=(s[-width+x]+s[x-1]+s[-width+x-1]+s[-width+x+1]+s[width+x-1]+s[width+x]+s[x+1]+s[width+x+1])>>3;
_>        }
_>        for(int y=1; y<height-1; y++){
_>            const auto s=buf.data()+y*width;
_>            const auto d=image.data()+y*width;
_>            for(int x=1; x<width-1; x++) if(s[x]!=0xffffff)
_>                d[x]=(s[-width+x]+s[x-1]+s[-width+x-1]+s[-width+x+1]+s[width+x-1]+s[width+x]+s[x+1]+s[width+x+1])>>3;
_>        }
_>    }
_>    return timer.elapsed().wall/1000000;
_>}
_>


В таком виде GCC автовекторизирует и на x64 и на x32. Но я бы не сказал что тут прям какое-то принципиальное изменение в коде, это скорее недоработка автовекторизатора, тем более он справлялся с векторизацией на x32 без такого изменения (я бы ещё понял если бы наоборот, на x32 он не смог).
Возможно стоит отправить этот пример в их bug tracker?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.