Комментарии 48
ХабраРедактор не забыл про кат, а вы забыли
+1
А где тесты сравнения скорости вычисления вашего «заклятого» кода и обычного, через операторы +-*/ ???
+4
Ммм. Не ставил задачи протестировать разницу в скорости. Но сразу могу сказать, что «заклятый» код выполняет непосредственно сопроцессор в связке с процессором. Код на C# претерпит jit-компиляцию, которая скорее всего приведет к такой же конструкции.
Однако цель статьи не демонстрация преимущества скорости конкретного примера, а скорее демонстрация того, как можно использовать дополнительные возможности процессора, чего не может компилятор C#. Например, Вы можете писать на инструкциях SSE 2,3,4 и более, 3DNow (технология AMD) и прочих. В принципе, можно воспользоваться утилитой .NET ngen.exe, чтобы сгенерировать образы нативных кодов для Ваших .NET сборок, но не всегда это получается.
Кроме этого, в этой статье только пример того, как это делается, я упоминал, что при наличии интереса можно развить это направление и динамически генерировать себе любой код. При это не надо никаких MSIL инъекций и прочего, пишите на нативном коде и используйте его в своих программах на C#
Однако цель статьи не демонстрация преимущества скорости конкретного примера, а скорее демонстрация того, как можно использовать дополнительные возможности процессора, чего не может компилятор C#. Например, Вы можете писать на инструкциях SSE 2,3,4 и более, 3DNow (технология AMD) и прочих. В принципе, можно воспользоваться утилитой .NET ngen.exe, чтобы сгенерировать образы нативных кодов для Ваших .NET сборок, но не всегда это получается.
Кроме этого, в этой статье только пример того, как это делается, я упоминал, что при наличии интереса можно развить это направление и динамически генерировать себе любой код. При это не надо никаких MSIL инъекций и прочего, пишите на нативном коде и используйте его в своих программах на C#
0
Например, Вы можете писать на инструкциях SSE 2,3,4 и более, 3DNow (технология AMD) и прочих.
Насчёт SSE лучше смотрите в сторону Mono.Simd.
Надеюсь и в родном Microsoft .Net такое со временем появится.
В принципе, можно воспользоваться утилитой .NET ngen.exe, чтобы сгенерировать образы нативных кодов для Ваших .NET сборок, но не всегда это получается.
В большинстве случаев это и не нужно.
Если действительно есть «узкое место» в производительности, намного логичнее реализовать его в native dll.
… можно развить это направление и динамически генерировать себе любой код. При это не надо никаких MSIL инъекций и прочего, пишите на нативном коде и используйте его в своих программах на C#
Протестируйте производительность своего варианта.
После этого Вы и сами поймёте почему практическая ценность Вашего решения близится к 0.
0
с появлением лямбда выражений, и если нужны операции обработки большой коллекции, перед первым вызовом можно генерировать подобный код на основе лямбда дерева, а дальше только вызывать его для обработки элемента коллекции. будет больше чем занятно) и что-то мне кажется, что кто-то уже должен был подобное реализовать…
0
Практическая ценность?
+2
Кодогенерация на нативном коде. Быстро работает, есть ощущение, что процессор делает то, что Вы ему сказали =)
Мне очень пригодилось для мат.расчетов в программе, которую я написал. Вводите формулу, программа ее парсит и генерирует нативный код. Первая версия генерировала с помощью Reflection API, но потом отказался ради увеличения скорости.
Мне очень пригодилось для мат.расчетов в программе, которую я написал. Вводите формулу, программа ее парсит и генерирует нативный код. Первая версия генерировала с помощью Reflection API, но потом отказался ради увеличения скорости.
+1
Ну как же? Вот решили Вас, предположим, уволить, и Вам требуется оставить после себя код, обладающий минимальной совместимостью и максимальной сложностью сопровождения. Что будете делать? =)
+6
НЛО прилетело и опубликовало эту надпись здесь
А) JIT-компилятор возможно знает SSE и прочие (сомневаюсь правда). Статья для тех, кто хочет делать это своими руками.
Б) С++ затем, что в нем есть указатели на функции, что позволяет передать управление в начало массива. Да, можно подключить функцию, но ведь и можно на С++ написать обертку (я упоминал об этом) и генерировать любой код в любое удобное для Вас время. Причем код нативный с удобными для Вас инструкциями процессора.
С) Когда я этим начал заниматься, Mono был на стадии зачатия, даже MonoDevelop еще не существовала.
Б) С++ затем, что в нем есть указатели на функции, что позволяет передать управление в начало массива. Да, можно подключить функцию, но ведь и можно на С++ написать обертку (я упоминал об этом) и генерировать любой код в любое удобное для Вас время. Причем код нативный с удобными для Вас инструкциями процессора.
С) Когда я этим начал заниматься, Mono был на стадии зачатия, даже MonoDevelop еще не существовала.
-9
НЛО прилетело и опубликовало эту надпись здесь
jit-компилятор отлично знает про SSE и прочие
0
НЛО прилетело и опубликовало эту надпись здесь
Ну как бы в статье написано как не компилить на Си, а заливать код в память (причем с учетом «архитектуры») и выполнять оттуда. Это несколько другое.
А чтобы jit-у лучше жилось на текущей машине, то можно воспользоваться ngen.exe, которая создаст для Вашей сборки образ нативного кода, который будет учитывать разные особенности машины, и .NET будет этот оптимизированный образ использовать при выполнении кода из Вашей сборки.
А чтобы jit-у лучше жилось на текущей машине, то можно воспользоваться ngen.exe, которая создаст для Вашей сборки образ нативного кода, который будет учитывать разные особенности машины, и .NET будет этот оптимизированный образ использовать при выполнении кода из Вашей сборки.
-1
НЛО прилетело и опубликовало эту надпись здесь
Согласен. А у Вас есть вариант как динамически сгенерировать нативный код и тут же его подключить к основному языку разработки (в моем случае C#)?
0
НЛО прилетело и опубликовало эту надпись здесь
C# не предназначен для работы с нативным кодом. Если вам нужен MSIL (который замечательно компилируется JIT-ом в MMX, SSE, 3DNow! и прочие расширения в зависимости от текущего процессора), то это Reflection.Emit.
Если бы вы написали разборщик выражений, который бы через Reflection.Emit генерировал MSIL — пользы было бы больше.
Если бы вы написали разборщик выражений, который бы через Reflection.Emit генерировал MSIL — пользы было бы больше.
0
рискну утверждать, что интегрированный FPU в CPU был в процессорах Intel уже в Pentium (если не раньше).
+3
в 486
+2
угу, 386DX и 486DX
+4
У 386DX встроенного сопра не было. От SX он отличался шириной шины данных.
0
и вправду не было…
ru.wikipedia.org/wiki/Intel_80386
ru.wikipedia.org/wiki/Intel_80386
0
Да, утверждение, что он появился в PIII, меня тоже неслабо развеселило…
+2
вообще, если все это нужно для реализации математических вычислений, то еще лет 7 назад Intel и AMD уже распространяли собственные библиотеки с реализацией всех основных функций, максимально использующие возможности процессоров
есть также открытые коды реализации функций из матлаба, но в них было много ошибок, и нужно пошагово проверять реализацию алгоритмов, хотя может быть с годами часть пофиксили
но в целом, если алгоритм нормально написан, то его можно реализовать просто на C#, с небольшими вставками MSIL-ассемблера, и скорость работы будет приемлемая
опять же, для SSE можно вызывать библиотеки от производителя процессора
есть также открытые коды реализации функций из матлаба, но в них было много ошибок, и нужно пошагово проверять реализацию алгоритмов, хотя может быть с годами часть пофиксили
но в целом, если алгоритм нормально написан, то его можно реализовать просто на C#, с небольшими вставками MSIL-ассемблера, и скорость работы будет приемлемая
опять же, для SSE можно вызывать библиотеки от производителя процессора
0
В плюсах встроенный ассемблер (__asm) не жует MMX?
0
Генерацией на MSIL я баловался раньше. Это вообще говоря намного проще.
Но как ни крути, jit не всегда улавливает мысли разработчика. Я честно не знаю, не видел ядра jit-компилятора. Но вот вопрос: если мы работаем с огромным массивом данных (double) (миллиарды элементов), то мы можем обрабатывать сразу по 2-4 элемента в такт с помощью SSE2 — 4; вот и скажите, jit-компилятор соптимизирует это в реально возможный код на машинных кодах (кстати, не все компиляторы С++ это могу, если не все. Приходится это делать в отдельном проекте на ассемблере и объектный файл прикручивать к проекту С++)?
Но как ни крути, jit не всегда улавливает мысли разработчика. Я честно не знаю, не видел ядра jit-компилятора. Но вот вопрос: если мы работаем с огромным массивом данных (double) (миллиарды элементов), то мы можем обрабатывать сразу по 2-4 элемента в такт с помощью SSE2 — 4; вот и скажите, jit-компилятор соптимизирует это в реально возможный код на машинных кодах (кстати, не все компиляторы С++ это могу, если не все. Приходится это делать в отдельном проекте на ассемблере и объектный файл прикручивать к проекту С++)?
0
Меня терзают смутные сомнения, что JIT-компилер отлично знает об особенностях текущей платформы, на которой выполняется код, и сразу генерирует оптимизированный под нее код. Это какбэ одна из задач JIT-компилятора.
+1
Это хорошо для обучения программированию FPU. Практической ценности здесь нет.
Оптимизация, о которой вы говорите — это МИКРО-оптимизация, которая влияет разве что при брутальном переборе в 8 потоков чего нибудь супер-математического.
Оптимизация, о которой вы говорите — это МИКРО-оптимизация, которая влияет разве что при брутальном переборе в 8 потоков чего нибудь супер-математического.
+1
На хабре неуместны статьи, помогающие тем, у кого редкие цели и математические задачи?
0
Т.е. не так я хотел сказать, пардон.
«Не имеют практической ценности статьи, помогающие достичь непопулярных целей, с математической основой?»
И как это понять, «хорошо для обучения программированию FPU», но «практической ценности нет», а зачем тогда обучение?
Задачи всякие бывают, и часто упирающиеся в вычисления, а не то, что попсовей, типа растолкать куда-то записи по таблицам в БД. При этом программист может предпочитать свой любимый C#, и, я думаю, наверняка сейчас многие с интересом прочтут эту статью, и возможно «давно ее ждали».
«Не имеют практической ценности статьи, помогающие достичь непопулярных целей, с математической основой?»
И как это понять, «хорошо для обучения программированию FPU», но «практической ценности нет», а зачем тогда обучение?
Задачи всякие бывают, и часто упирающиеся в вычисления, а не то, что попсовей, типа растолкать куда-то записи по таблицам в БД. При этом программист может предпочитать свой любимый C#, и, я думаю, наверняка сейчас многие с интересом прочтут эту статью, и возможно «давно ее ждали».
0
Хотелось бы чтобы каждый из Вас, прочитав статью, извлек из нее что-то полезное для себя.
Надеюсь, кому-нибудь это поможет в решении той или иной задачи (не важно какого проекта).
Надеюсь, кому-нибудь это поможет в решении той или иной задачи (не важно какого проекта).
0
Спасибо lostmsu за наводку на Marshal.GetDelegateForFunctionPointer().
Таким образом, мы можем исключить С++ и переписать все на C#.
Вот здесь есть пример использования генерации нативного кода непосредственно на C#.
Пройдя по ссылке увидите сам способ реализации, а как заполнять массив опкодами я рассказал в моем посте.
Таким образом, мы можем исключить С++ и переписать все на C#.
Вот здесь есть пример использования генерации нативного кода непосредственно на C#.
Пройдя по ссылке увидите сам способ реализации, а как заполнять массив опкодами я рассказал в моем посте.
+1
НЛО прилетело и опубликовало эту надпись здесь
извращение это — заниматься низкоуровневым программированием из языка высокого уровня
0
Бред — с тем же успехом можно было написать «Программирование сопроцессора из плагина Winamp/Foobar/utorrent/С++/VB/Java»
+2
А мне нравится.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Программирование сопроцессора на C#? Да!