Производительность C# - должен ли я писать вычислительные тяжелые методы в c++?



Я создаю прототип для количественной библиотеки, которая выполняет некоторый анализ сигналов с использованием методов обработки изображений. Я построил первоначальный прототип полностью на C#, но производительность не так хороша, как ожидалось. Большая часть вычислений выполняется с помощью тяжелых матричных вычислений, и они занимают большую часть времени.



Мне интересно, Стоит ли писать интерфейс C++ / CLI для неуправляемого кода C++. Кто-нибудь когда-нибудь проходил через это? Другие предложения по оптимизации C# представление приветствуется.

806   8  

8 ответов:

Было время, когда определенно было бы лучше писать на C / C++, но оптимизатор C# и JIT настолько хороши сейчас, что для чистой математики, вероятно, нет никакой разницы.

Разница возникает, когда приходится иметь дело с памятью и, возможно, массивами. Тем не менее, я бы все равно работал с C# (или F#), а затем оптимизировал горячие точки. JIT действительно хорош в оптимизации небольших, недолговечных объектов.

С массивами вам придется беспокоиться о том, что C# выполняет проверку границ для каждого доступа. Прочитай это:

Http://blogs.msdn.com/b/clrcodegeneration/archive/2009/08/13/array-bounds-check-elimination-in-the-clr.aspx

Проверьте сами - я обнаружил, что C# сравним - иногда быстрее.

Здесь трудно дать окончательный ответ, но если проблема в производительности, я бы нашел проверенную временем библиотеку с нужной вам производительностью и завернул ее.

Что - то простое, например умножение или деление, не сильно отличается между c++ и c#-компилятор c++ имеет оптимизатор, а среда CLR имеет JITer по требованию, который выполняет оптимизацию. Таким образом, теоретически c++ будет превосходить c# только при первом вызове.

Однако теория и практика-это не одно и то же. С более сложные алгоритмы вы также столкнетесь с различиями между менеджерами памяти и зрелостью методов оптимизации. Если вам нужны анекдотические доказательства, вы можете найти здесь некоторые математически тяжелые сравнения .

Лично я считаю, что выполнение тяжелых вычислений в родной библиотеке и использование c++ / CLI для ее вызова дает хороший толчок , когда вычисления являются самым большим узким местом. Как всегда, убедитесь, что это так, прежде чем делать какую-либо оптимизацию.

Матричная математика, на мой взгляд, лучше всего выполняется в машинном коде. Даже библиотеки C++ обычно допускают привязку к реализации более низкого уровня, такой какLAPACK .

Есть порт C# LAPACK здесь (также C# BLAS на том же сайте), который вы можете попробовать, но я был бы удивлен, если бы это было быстрее, чем машинный код.

Я проделал большую работу по обработке изображений в C# и, да, я обычно использую машинный код для сверхмощного кода, где важна производительность, но я использовал только PInvokes, а не интерфейс C++/CLI. Правда, много времени на это не потребуется.

Существует довольно много хороших .NET-профайлеров. В Красные ворота Один мой личный фаворит. Это может помочь вам визуализировать, где находятся узкие места.

Единственный приемлемый языковой бенчмарк: http://shootout.alioth.debian.org/

Смотрите сами.

Производительность математических вычислений в C#довольно низкая. Я был поражен, обнаружив, насколько медленными являются математические вычисления в C#. Просто напишите цикл в C# и C++, имеющий несколько умножения, Sin, Cos, ... и разница огромна.

Я не знаю управляемый C++, но imlpementing все это в неуправляемом C++ abd я бы umagine разоблачение гранулярных интерфейсов через P / Invoke должно иметь мало perfromance хит.

Это то, что я сделал для тяжелого изображения в реальном времени обработка.

Я построил первоначальный прототип полностью на C#, но производительность не так хороша, как ожидалось.

Тогда у вас есть два варианта:

Создайте еще один прототип на языке C++ и посмотрите, как он будет сравниваться, или оптимизируйте свой код на языке C#. Независимо от того, на каком языке вы пишете, ваш код не будет быстрым, пока вы не профилируете и не оптимизируете его. Это особенно верно в C++. Если вы напишете максимально быструю реализацию в C# и сравните ее с самая быстрая возможная реализация в C++, тогда версия C++, скорее всего, будет быстрее. Но это будет стоить с точки зрения времени разработки. Написать эффективный код на языке C++ не так уж и просто. Если вы новичок в этом языке, то, скорее всего, напишете очень неэффективный код, особенно если вы пришли из C# или Java, где все делается по-другому и имеет разные затраты.

Если вы просто пишете рабочую реализацию, не слишком беспокоясь о производительности, то я предполагая, что версия C#, вероятно, будет быстрее.

Но это действительно зависит от того, какую производительность вы ищете (и не в последнюю очередь, насколько дороги операции, которые вам нужно выполнить. Есть накладные расходы, связанные с переходом от управляемого кода к машинному, поэтому не стоит тратить время на короткие операции, которые выполняются часто.

Шифрование чисел в C++ может быть таким же быстрым, как и код, написанный на Fortran (плюс-минус несколько процентов), но для этого вам нужно использовать множество передовых методов (шаблоны выражений и множество метапрограммирования) или некоторые довольно сложные библиотеки, которые реализуют его для вас.

Стоит ли это того? Или можно ли сделать C# быстро достаточно для ваших нужд?

Вы должны писать вычислительные тяжелые программы на C++, вы не можете достичь даже близко к производительности C++, оптимизируя C#. Накладные расходы на вызов оболочек незначительны, если предположить, что вычисление занимает значительное время. Я занимался кодированием как на C++, так и на C# и никогда не видел случая, когда код .NET framework был бы сравним с C++. Есть несколько примеров, где C# работает лучше, но это было лучше из-за отсутствия соответствующих библиотек или плохого кодирования в C++. Если вы умеете писать код одинаково хорошо работает на C# и C++, я бы написал код производительности на C++, а все остальное-на C#.

Если x-лучший в мире программист на C++, а y-лучший программист на C#, то в большинстве случаев x может писать код быстрее, чем y. однако y может закончить кодирование быстрее, чем x в большинстве случаев.

Comments

    Ничего не найдено.