Здравствуйте, gandjustas, Вы писали:
_>>Кроме отсутствия автовекторизации, C# (а точнее .net) обладает ещё целым букетом замедляющих факторов, происходящих из самого устройства платформы. Это не говоря уже о просто слабом оптимизаторе. G>Это уже твои фантазии. Таких "замедляющих факторов" в любом языке полно, даже в c++. Более того, почти любые гарантии со стороны языка небесплатны. Супер оптимальный код будет супер небезопасным. А достаточно надежный код будет иметь "букет замедляющих факторов".
Что-то я не понял этого твоего высказвания) В первом предложение ты выступаешь против моего тезиса, а в следующих 4-ёх излагаешь подтверждающие его аргументы. )))
Да, а насчёт компромисса скорость/безопасность я собственно и не спорил. Хотя такое всё же не всегда происходит. К примеру такие вещи как "все функции виртуальные" и отсутствие полноценных нессылочных типов явно не приводят к какому-то увеличению безопасности... )
_>Да, а насчёт компромисса скорость/безопасность я собственно и не спорил. Хотя такое всё же не всегда происходит. К примеру такие вещи как "все функции виртуальные" и отсутствие полноценных нессылочных типов явно не приводят к какому-то увеличению безопасности... )
А где это в .Net "все функции виртуальные"? Ты с Java не спутал?
Другое дело, что С++ может больше использовать инлайн, что может приводить к ускорении при частом вызове таких функций.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
_>>>И какое это имеет отношение к автовекторизации? ) S>>К авто не имеет, а к векторизации полное.
_>Ну так тогда и код не будет одинаковым, даже близко. ))) В C++ останется изначальный простенький цикл, а в C# надо будет нагородить всяких ужасов. А в вопросе речь шла об одинаковом коде.
А зачем городить? Наоборот для решения конкретной задачи свой инструмент. S>>
S>> Вектор поддержкой SIMD типы, такие как Vector4, Matrix3x2, Plane, и Quaternion.
S>>Если тебе нужно решать задачу работы с матрицами выбирай нужные типы S>>http://www.cyberforum.ru/post7461490.html S>>http://habrahabr.ru/post/219841/
_>Это всё было в C++ (в виде библиотек) лет 15 назад и от этого уже давно уходят к совсем другим решениям. А в C# только сейчас к этому пришли. Поздравляю. )))
Это не C#, это .Net. Рано или поздно придут и к другим решениям и бОльшей оптимизации компилятора. Пока для Net куча других задач, а главное быстрота и удобство и безопасность программирования.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, alexzz, Вы писали:
A>Я написал свой вариант на C#, работает ещё быстрее оригинала, в 2,3 раза: http://pastebin.com/v2ZMRu86
A>original: 9881 A>optimized: 4342
Это хорошо, только вы ведь использовали internal unsafe class Program и fixed указатели для обработки массива. Немного волшебства и в этом соревновании двух бегунов C# пришел к финишу вторым, а С++ предпоследним
A>У меня давно сложилось и продолжает укрепляться подозрение, что C++ ощутимо (хотя бы раза в два) быстрее C# только там, где повезёт и задачу можно векторизовать, и компилятор C++ сумеет при этом применить свою векторизовальную магию. А если не повезёт, то быстрее может и вообще не получиться.
PM>>По ссылкам в новости о ScyllaDB написано, как получился такой результат. Разработчики решали конкретные проблемы, а не сравнивали результаты синтетических тестов.
A>Про то, что ускорение в 10 раз вызвал именно переход с Java на C++, упоминается лишь в желтушном заголовке новости.
В заголовок новости не поместилась информация о том, что они:
оптимизировали работу с памятью (а память по факту уже давно является многоуровневой системой кэшей)
запустили user-space TCP/IP стек для определенного вида сетевых карт
и пока не полностью реализовали все функции
У меня есть сомнения, что первые 2 пункта легко реализуемы в управляемых средах (не знаю, добавили ли уже в Java value types)
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
_>>>Кроме отсутствия автовекторизации, C# (а точнее .net) обладает ещё целым букетом замедляющих факторов, происходящих из самого устройства платформы. Это не говоря уже о просто слабом оптимизаторе. G>>Это уже твои фантазии. Таких "замедляющих факторов" в любом языке полно, даже в c++. Более того, почти любые гарантии со стороны языка небесплатны. Супер оптимальный код будет супер небезопасным. А достаточно надежный код будет иметь "букет замедляющих факторов".
_>Что-то я не понял этого твоего высказвания) В первом предложение ты выступаешь против моего тезиса, а в следующих 4-ёх излагаешь подтверждающие его аргументы. )))
Специально для тебя повторю — замедляющих факторов полно в любом языке. Даже в С++ (одни смартпоинтеры чего стоят). А дальше логичный вывод — чем безопаснее программа, тем больше "замедляющих факторов" будет.
_>Да, а насчёт компромисса скорость/безопасность я собственно и не спорил. Хотя такое всё же не всегда происходит. К примеру такие вещи как "все функции виртуальные" и отсутствие полноценных нессылочных типов явно не приводят к какому-то увеличению безопасности... )
Это ты про Java надо полагать? Или решил показать незнание?
Так вот Java умеет девиртуализировать вызовы и размещать объекты на стеке. Руками не контролируется, делается путем анализа кода в JIT. Именно поэтому Java в математике весьма неплохо себя показывает. Так что недостаток языка вполне может быть (и на практике будет) скомпенсирован рантаймом. А вот когда дело касается реальной безопасности то, здравствуй "букет замедляющих факторов", независимо от языка.
Здравствуйте, Serginio1, Вы писали:
_>>Да, а насчёт компромисса скорость/безопасность я собственно и не спорил. Хотя такое всё же не всегда происходит. К примеру такие вещи как "все функции виртуальные" и отсутствие полноценных нессылочных типов явно не приводят к какому-то увеличению безопасности... ) S> А где это в .Net "все функции виртуальные"? Ты с Java не спутал?
Это было про языки программирования в целом. Тем более, что у нас как раз такой сабж. )
S>Другое дело, что С++ может больше использовать инлайн, что может приводить к ускорении при частом вызове таких функций.
Да, совершенно верно верно. Это один из главных причин. А другая главная причина — это уменьшение косвенности (которую ненавидят кэши процессора).
Здравствуйте, Serginio1, Вы писали:
_>>Это всё было в C++ (в виде библиотек) лет 15 назад и от этого уже давно уходят к совсем другим решениям. А в C# только сейчас к этому пришли. Поздравляю. ))) S> Это не C#, это .Net. Рано или поздно придут и к другим решениям и бОльшей оптимизации компилятора. Пока для Net куча других задач, а главное быстрота и удобство и безопасность программирования.
Кстати, в C++ от этого уходили когда-то исключительно из-за неудобства такой работы для программиста. Но сейчас актуальны и другие причины. К примеру на современных компьютерах при таком подходе необходимо использовать уже vector8, а не vector4. А в ближайшем будущем понадобится уже и vector16. )))
Здравствуйте, gandjustas, Вы писали:
_>>Что-то я не понял этого твоего высказвания) В первом предложение ты выступаешь против моего тезиса, а в следующих 4-ёх излагаешь подтверждающие его аргументы. ))) G>Специально для тебя повторю — замедляющих факторов полно в любом языке. Даже в С++ (одни смартпоинтеры чего стоят). А дальше логичный вывод — чем безопаснее программа, тем больше "замедляющих факторов" будет.
Насчёт безопасности никто и не спорит (ну точнее это не всегда так, но во многих случаях действительно верно). Но я то просто утверждал насчёт букета замедляющих факторов, вне зависимости от причины их появления (ради безопасности или ещё почему-то). Т.е. ты опять же подтверждаешь мой изначальный тезис.
Ну и насчёт смартпоинтеров... Интересно глянуть где ты там найдёшь замедление скажем у std::unique_ptr (основной современный инструмент для таких целей).
_>>Да, а насчёт компромисса скорость/безопасность я собственно и не спорил. Хотя такое всё же не всегда происходит. К примеру такие вещи как "все функции виртуальные" и отсутствие полноценных нессылочных типов явно не приводят к какому-то увеличению безопасности... ) G>Это ты про Java надо полагать? Или решил показать незнание?
И Java и многие другие. )
G>Так вот Java умеет девиртуализировать вызовы и размещать объекты на стеке. Руками не контролируется, делается путем анализа кода в JIT. Именно поэтому Java в математике весьма неплохо себя показывает. Так что недостаток языка вполне может быть (и на практике будет) скомпенсирован рантаймом. А вот когда дело касается реальной безопасности то, здравствуй "букет замедляющих факторов", независимо от языка.
Да, для меня было весьма неожиданно, что жабка обошла C# (хотя и совсем на копейки) в обсуждаемом выше тесте. Но до реального быстродействия ей всё равно далеко.
Здравствуйте, alex_public, Вы писали:
A>>У меня давно сложилось и продолжает укрепляться подозрение, что C++ ощутимо (хотя бы раза в два) быстрее C# только там, где повезёт и задачу можно векторизовать, и компилятор C++ сумеет при этом применить свою векторизовальную магию. А если не повезёт, то быстрее может и вообще не получиться.
_>Это неверное подозрение. Что очевидно и из практики (см. ссылку выше, там есть цифры для C++ без simd) и из общетеоретических соображений. Кроме отсутствия автовекторизации, C# (а точнее .net) обладает ещё целым букетом замедляющих факторов, происходящих из самого устройства платформы. Это не говоря уже о просто слабом оптимизаторе.
Но ведь твоя таблица как раз подтверждает мои подозрения: C++ no-simd — 3,5 c, мой код на C# — 4,6 с. Разница в 1,3 раза. Не в два и даже не в полтора. Это как 1,3 vs 1,0 с (и то, и другое быстро) или 130 vs 100 с (и то, и другое медленно). Ощутимо быстрее C++ стал, только когда компилятор сумел что-то векторизовать. Я об этом и говорил — С++ становится ощутимо быстр, если повезёт с векторизацией; если нет, то С++ либо незначительно быстрее, либо вообще не быстрее.
Кстати, можно посмотреть бинарники C++, которые показывают 1,3 и 0,6 с? Мне любопытно посмотреть, что там наколдовано.
И ещё, пользуясь случаем, вопросы не в тему:
— Код делает HDR-blur? Если нет, то почему int[], а не byte[]?
— Зачем там условие внутри циклов?
Здравствуйте, PM, Вы писали:
A>>original: 9881 A>>optimized: 4342
PM>Это хорошо, только вы ведь использовали internal unsafe class Program и fixed указатели для обработки массива.
Это же штатный функционал. Надо — используешь, не надо — не используешь. Я давно заметил, что у некоторых товарищей (обычно в основном пишущих на C++) имеется фобия на указатели в C#, но ни я, ни C# в этом не виноваты
Здравствуйте, alexzz, Вы писали:
A>Но ведь твоя таблица как раз подтверждает мои подозрения: C++ no-simd — 3,5 c, мой код на C# — 4,6 с. Разница в 1,3 раза. Не в два и даже не в полтора. Это как 1,3 vs 1,0 с (и то, и другое быстро) или 130 vs 100 с (и то, и другое медленно). Ощутимо быстрее C++ стал, только когда компилятор сумел что-то векторизовать. Я об этом и говорил — С++ становится ощутимо быстр, если повезёт с векторизацией; если нет, то С++ либо незначительно быстрее, либо вообще не быстрее.
То есть получается, что джава вообще в хвосте плетется как всегда, да?
Здравствуйте, alexzz, Вы писали: _>>Это неверное подозрение. Что очевидно и из практики (см. ссылку выше, там есть цифры для C++ без simd) и из общетеоретических соображений. Кроме отсутствия автовекторизации, C# (а точнее .net) обладает ещё целым букетом замедляющих факторов, происходящих из самого устройства платформы. Это не говоря уже о просто слабом оптимизаторе. A>Но ведь твоя таблица как раз подтверждает мои подозрения: C++ no-simd — 3,5 c, мой код на C# — 4,6 с. Разница в 1,3 раза. Не в два и даже не в полтора. Это как 1,3 vs 1,0 с (и то, и другое быстро) или 130 vs 100 с (и то, и другое медленно). Ощутимо быстрее C++ стал, только когда компилятор сумел что-то векторизовать. Я об этом и говорил — С++ становится ощутимо быстр, если повезёт с векторизацией; если нет, то С++ либо незначительно быстрее, либо вообще не быстрее.
Ну во-первых твой код — это не C#, а unsafe C#, что существенно. Причём даже не просто unsafe (в смысле модификатора), а ещё и дико страшный из-за необходимости обхода всех штатных тормозов. Т.е. писать так код постоянно — это убиться. ))) А во-вторых для подобных циклов компилятору C++ "повезёт" всегда. Т.е. эти 3,5 секунды — это исключительно для полноты теста, а на практике их никогда не будет. A>Кстати, можно посмотреть бинарники C++, которые показывают 1,3 и 0,6 с? Мне любопытно посмотреть, что там наколдовано.
Эмм, так код для варианта 3,5 секунды и 1,3 секунды абсолютно одинаковый. Разница только в опциях компилятора. И этот код я уже показывал в том обсуждение: http://rsdn.ru/forum/flame.comp/6072279.1
Что касается варианта с 0,6 секунды, то его сейчас под рукой нет, но я могу его описать: там уже используется ручная векторизация (intrinsics), а не автовекторизация. И да, код там уже не такой симпатичный, но зато выжимает из процессора всю теоретически допустимую мощь (в расчёте на ядро). A>И ещё, пользуясь случаем, вопросы не в тему: A>- Код делает HDR-blur? Если нет, то почему int[], а не byte[]?
Ну вообще то изначально этот код был просто специально для теста выбран (до него кстати в тесте был другой, с плавающей точкой, но там возникли большие неоднозначности в сравнения разных языков). Но у него естественно есть реальный прообраз. И нет, это естественно не blur (зачем может быть blur настолько многократный?), а одна из разновидностей клеточного автомата. Кстати, сразу замечу, что подобные автоматы — это не обязательно весёлая игрушка программистов. К примеру подобный код может моделировать различные физические процессы (соответствующие диф. уравнения совпадают), скажем распространения тепла в твёрдом теле. Ну и в любом случае, даже без понимания сути процессов, таким образом можно получать весьма любопытные картинки. Т.е. вот даже та жалкая тысяча итераций из нашего теста даёт вот такое:
Скрытый текст
А если сделать в 100 раз больше итерация, то пойдут уже весьма сюрреалистичные картинки. ) A>- Зачем там условие внутри циклов?
1. С точки зрения теста хотелось что посложнее (данный if сильно гадит оптимизатору в любом языке).
2. С точки зрения клеточного автомата это означает, что белые точки (задаются в изначальном изображение) немодифицируемы.
3. С точки зрения моделирования процессов (того же тепла в твёрдом теле) это означает наличие источников тепла с фиксированной температурой.
Здравствуйте, alex_public, Вы писали:
_>Ну во-первых твой код — это не C#, а unsafe C#, что существенно. Причём даже не просто unsafe (в смысле модификатора), а ещё и дико страшный из-за необходимости обхода всех штатных тормозов.
Не понял конец фразы. Тормоза, связанные с закреплением объектов в памяти, они как Лохнесское чудовище — все про них слышали, но никто не видел. Надо просто соблюдать рекомендации.
_>Т.е. писать так код постоянно — это убиться. )))
Навскидку для 90% кода скорость вообще не важна — делаешь его красивым и удобным в обслуживании. Для ещё 9% просто используешь быстрый алгоритм, подходящие типы коллекций, многопоточность. В оставшихся случаях можно пошаманить:
— самодельные специфические коллекции,
— unsafe,
— Mono.Simd / System.Numerics,
— вызов нативного кода (самый неудобный вариант).
Короче, такого кода, где unsafe имеет смысл, надо пол-процента (если вообще надо). И пофиг, как он выглядит. Ты же не пишешь весь свой код интринзиками.
_>Ну вообще то изначально этот код был просто специально для теста выбран (до него кстати в тесте был другой, с плавающей точкой, но там возникли большие неоднозначности в сравнения разных языков). Но у него естественно есть реальный прообраз. И нет, это естественно не blur (зачем может быть blur настолько многократный?), а одна из разновидностей клеточного автомата.
Прикольно. Я свой вариант кода без изменений взял из моего старого исходника блюра Но раз это не он, то у меня надо заменить
var buffer = new int[image.Length];
на
var buffer = (int[])image.Clone();
Впрочем, на скорость расчётов это не влияет.
Имхо, с тысячами итераций тебе бы надо на GPU перейти, а не мучить С++.
О! Rico Mariani. Знаем, знаем. Пустослов известный. Больше всего он любит пи31415деть о процессе организации процесса улучшения процесса оптимизации процесса.
Здравствуйте, alexzz, Вы писали:
_>>Ну во-первых твой код — это не C#, а unsafe C#, что существенно. Причём даже не просто unsafe (в смысле модификатора), а ещё и дико страшный из-за необходимости обхода всех штатных тормозов. A>Не понял конец фразы. Тормоза, связанные с закреплением объектов в памяти, они как Лохнесское чудовище — все про них слышали, но никто не видел. Надо просто соблюдать рекомендации.
Нет, здесь речь шла о том, что ты используешь *array вместо array[], чтобы обойти штатные тормоза из-за проверки границ массива. И это явно не способствует красоте кода. )))
_>>Т.е. писать так код постоянно — это убиться. ))) A>Навскидку для 90% кода скорость вообще не важна — делаешь его красивым и удобным в обслуживании. Для ещё 9% просто используешь быстрый алгоритм, подходящие типы коллекций, многопоточность. В оставшихся случаях можно пошаманить: A>- самодельные специфические коллекции, A>- unsafe, A>- Mono.Simd / System.Numerics, A>- вызов нативного кода (самый неудобный вариант). A>Короче, такого кода, где unsafe имеет смысл, надо пол-процента (если вообще надо). И пофиг, как он выглядит. Ты же не пишешь весь свой код интринзиками.
Всё верно. И на C# и на C++ можно создать решение как в красивом и удобном стиле, так и в страшном и неудобном, но зато где-то в 2 раза более быстром (хотя для C++ это уже верно только для случаев с SIMD, т.к. в других случаях штатный оптимизатор круче любого спеца по ассемблеру). Только есть один нюанс: красивое решение на C# более чем в 6 раз медленнее красивого решения на C++.
Ну точнее если говорить по честному, то в 6+ раз оно будет быстрее только на подобном коде (с обработкой массивов и т.п.), а в обычном коде скорее всего будет 2+ раза. Но это тоже совсем не мало. ))) Да и обработка массивов тоже частенько встречается. )
A>Имхо, с тысячами итераций тебе бы надо на GPU перейти, а не мучить С++.
Ну вообще то по реальным делам у меня скорее вещи типа blur'a возникают (причём в реальном времени), а не конечные автоматы. Только последние гораздо удобнее для подобного теста, при почти одинаковом коде.
Но вообще может и попробую здесь GPU в ближайшее время — с появлением openacc это стало настолько же тривиально, как и распараллеливания по ядрам CPU с помощью openmp.
Здравствуйте, alex_public, Вы писали:
_>Нет, здесь речь шла о том, что ты используешь *array вместо array[], чтобы обойти штатные тормоза из-за проверки границ массива. И это явно не способствует красоте кода. )))
Нифига, звёздочки в два раза красивее квадратных скобочек!
Имхо, это очень субъективно. Мне лично оригинал с кучей [] и вычислений индексов тоже сильно не нравится, как выглядит. Это скорее вопрос форматирования/оформления кода.
Здравствуйте, uncommon, Вы писали:
U>О! Rico Mariani. Знаем, знаем. Пустослов известный. Больше всего он любит пи31415деть о процессе организации процесса улучшения процесса оптимизации процесса.
Во-первых, там не пиздё%, а сплошные циферки.
Во-вторых, браузер Edge таки очень шустр.
Здравствуйте, alexzz, Вы писали:
A>У меня давно сложилось и продолжает укрепляться подозрение, что C++ ощутимо (хотя бы раза в два) быстрее C# только там, где повезёт и задачу можно векторизовать, и компилятор C++ сумеет при этом применить свою векторизовальную магию. А если не повезёт, то быстрее может и вообще не получиться.
1. Возьми тест из обсуждаемой статьи и сделай нормальный интерфейс для сортировки (например как у std::sort) — позволяющий сортировать последовательности из разных типов контейнеров, с разными типами элементов, и с разными предикатами сравнения, задаваемыми например замыканиями. Для пущей уверенности выключи любую автовекторизацию при замерах.
Здравствуйте, lpd, Вы писали:
lpd>Здравствуйте, xRAZORx, Вы писали:
RAZ>>Тут читал на хабре статью по сравнению производительности C# и C++. Сам джаву знаю плохо, но, может быть, кто-то производил замеры сам? Было бы интересно посмотреть сравнение, тем более везде говорят, что шарп и джава одинаковые по скорости.
lpd>Однажды скомпилировал на Java целочисленные вычисления(БПФ), написанные на C++. Разница была в 8 раз.
Здравствуйте, Nikе, Вы писали:
DR>>Встречал в сортировке по прозрачности, когда предметов в неправильном порядке мало и они идут друг за другом. N>Сортировка вставками?