Производительность C # - я должен написать вычислительные тяжелые методы в C ++? - PullRequest
3 голосов
/ 16 ноября 2010

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

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

Ответы [ 8 ]

3 голосов
/ 16 ноября 2010

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

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

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

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

3 голосов
/ 16 ноября 2010

Было время, когда было бы определенно лучше писать на 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 # сопоставим - иногда быстрее.

2 голосов
/ 16 ноября 2010

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

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

1 голос
/ 16 ноября 2010

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

Убедитесь сами.

1 голос
/ 16 ноября 2010

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

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

0 голосов
/ 16 ноября 2010

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

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

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

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

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

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

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

0 голосов
/ 16 ноября 2010

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

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

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

0 голосов
/ 16 ноября 2010

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

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

...