C ++ CLI.Нативные части написаны на чистом C ++, но скомпилированы в CLI так же быстро, как чистый нативный C ++? - PullRequest
13 голосов
/ 17 апреля 2011

Я хочу делегировать аудио вычисления на уровень C ++, но обрабатывать и редактировать аудио контент через графический интерфейс WPF.

Я кратко рассмотрел C ++ / CLI и хотел знать:

  • следует ли использовать C ++ / CLI в качестве промежуточного уровня между C # GUI и управлением звуком C ++
  • или я должен просто поместить свой код в C ++ / CLI и ожидать, что он будет скомпилирован таким же образом, а значит, и эффективнее.

РЕДАКТИРОВАТЬ: как может начаться пылающая война. Это ссылка, которая идет в тестовую игру , в которой C / C ++ явно указывается как победитель скорости. Я спрашиваю: должен ли я писать свой C ++ в C ++ Dll или в C ++ CLI-сборке.

Ответы [ 4 ]

24 голосов
/ 18 апреля 2011

В C ++ / CLI управляемые типы (например, ref class) и их члены компилируются в MSIL.Это означает отсутствие использования SIMD и гораздо меньшую оптимизацию (по крайней мере, в текущей версии .NET, и причины, приведенные Microsoft, не изменятся в ближайшее время, хотя они могут изменить свою оценку компромиссов).

Собственные типы, с другой стороны, могут быть скомпилированы либо в MSIL, либо в машинный код.Хотя Visual C ++ не имеет лучшего оптимизатора C ++ в мире, он очень и очень хорош.Поэтому я рекомендую компилировать в нативный код.Visual C ++ будет использовать взаимодействие C ++ при вызове между управляемым и нативным кодом, что очень эффективно (это та же технология internalcall, которая используется для всех встроенных функций .NET, таких как конкатенация строк).

В этом случае вы можете поместить свой критичный ко времени код в отдельный объектный файл (не в отдельную DLL!с #pragma managed(push, off) ... #pragma managed(pop).В любом случае вы получите максимальную оптимизацию и сможете использовать встроенные функции SIMD для очень быстрого кода.

5 голосов
/ 17 апреля 2011

Соединение уровня C ++ / CLI - это процесс маршаллинга, когда управляемое состояние преобразуется в примитивные типы, чтобы маршалировать на неуправляемый уровень, обрабатывать, а затем маршалировать обратно. В зависимости от вашего алгоритма (и прагматики для «обертывания» этого переходного слоя) лучше всего поддерживать сортировку как можно более ограниченной (малой).

Таким образом, это зависит от проблемы: самая простая проблема - это интерфейс, который отправляет немного примитивных данных через уровень C ++ / CLI, обрабатывает LONG время, а затем отправляет немного данных обратно (например, минимальные издержки на маршаллинг) , Если ваш алгоритм требует более обширного взаимодействия на уровне C ++ / CLI, он становится намного сложнее.

Преимущество "All C #" или "All Managed" состоит в том, что (1) пропускает этот уровень сортировки (который является накладным, а иногда утомительным в зависимости от работы), и (2) оптимизация времени выполнения, что движок .NET может сделать для конкретного компьютера, на котором выполняется код (который вы не можете иметь с собственным C / C ++ или неуправляемым кодом).

Я согласен с другими комментариями в этой теме, что вы должны / должны "протестировать" его в соответствии со своими сценариями. «Большой» слой C ++ / CLI с чувствительным к производительности переходом очень сложен из-за «упаковки / распаковки», которая (автоматически) происходит, когда вы продолжаете переходить между управляемым / неуправляемым.

Наконец, предельная предельная разница в производительности между гибридным «управляемым / неуправляемым» дизайном и «полностью управляемым» дизайном связана с компромиссами между: Может ли ядро ​​.NET выполнять специфичные для машины оптимизации кода .NET (например, используя преимущества машинно-ориентированных потоков / ядер / регистров), больший, чем «чистый нативный» код (который связан со сборкой смешанного режима), способен обрабатывать FAST, минуя. NET движок (который является переводчиком)?

Правда, хорошо написанный собственный код может «обнаруживать» потоки процессора, но, как правило, не может обнаруживать машинно-зависимые регистры (если они не скомпилированы для этой целевой платформы). Напротив, у нативного кода нет «накладных расходов» на прохождение среды выполнения .NET, которая представляет собой просто виртуальную машину (которая может быть «ускорена» за счет компиляции Just-In-Time некоторой логики для ее конкретного базового оборудования).

Сложная проблема. Сожалею. ИМХО, просто нет простых ответов на этот тип проблемы, если ваша проблема связана с «чувствительностью к производительности».

2 голосов
/ 17 апреля 2011

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

0 голосов
/ 17 апреля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...