Функции в собственном классе C ++ / CLI скомпилированы в MSIL или машинный код x64? - PullRequest
0 голосов
/ 22 марта 2019

Этот вопрос связан с другим моим вопросом под названием Вызов MASM PROC из C ++ / CLI в режиме x64 приводит к неожиданным проблемам с производительностью .Я не получаю никаких комментариев и ответов, но в конечном итоге я сам обнаружил, что проблема вызвана блокировками функций, которые вставляются компилятором всякий раз, когда управляемая функция вызывает неуправляемую, и наоборот.Я не буду вдаваться в подробности еще раз, потому что сегодня я не хочу останавливаться на другом следствии этого механизма настройки.

Чтобы обеспечить некоторый контекст для вопроса, моей проблемой была замена функции C ++для умножения целых чисел без знака на 64-128-бит в неуправляемом классе C ++ / CLI с помощью функции в файле MASM64 для повышения производительности.Замена ASM настолько проста, насколько это возможно:

AsmMul1 proc ; ?AsmMul1@@$$FYAX_K0AEA_K1@Z

; ecx  : Factor1
; edx  : Factor2
; [r8] : ProductL
; [r9] : ProductH

mov  rax, rcx            ; rax = Factor1
mul  rdx                 ; rdx:rax = Factor1 * Factor2
mov  qword ptr [r8], rax ; [r8] = ProductL
mov  qword ptr [r9], rdx ; [r9] = ProductH
ret

AsmMul1 endp

Я ожидал значительного повышения производительности, заменив скомпилированную функцию четырьмя 32-битными умножениями с простой инструкцией CPU MUL.Большим сюрпризом было то, что версия ASM была примерно в четыре раза медленнее (!), Чем версия C ++.После многих исследований и испытаний я обнаружил, что некоторые вызовы функций в C ++ / CLI включают в себя thunking, что, очевидно, является настолько сложной вещью, что занимает гораздо больше времени, чем сама thunked-функция.

После прочтениячто касается thunking , оказалось, что всякий раз, когда вы используете опцию компилятора /clr, соглашение о вызовах всех функций молча меняется на __ clrcall , что означает, что они становятся управляемыми функциями,Исключением являются функции, использующие встроенные функции компилятора, встроенный ASM и вызовы других DLL через dllimport - и, как показали мои тесты, это включает в себя функции, которые вызывают внешние функции ASM.

Пока все взаимодействующие функции используютСоглашение __clrcall (то есть управляется), не используется thunking, и все идет гладко.Как только управляемая / неуправляемая граница пересекается в любом направлении, включается громоподобный звук и производительность серьезно ухудшается.

Теперь, после этого длинного пролога, давайте перейдем к сути моего вопроса.Насколько я понимаю, соглашение __clrcall и переключатель компилятора /clr, помечая функцию в неуправляемом классе C ++, заставляют компилятор выдавать код MSIL.Я нашел это предложение в документации к __clrcall:

Когда вы помечаете функцию как __clrcall, вы указываете, что реализация функции должна быть MSIL, и что собственная функция точки входа не будет сгенерирована.

Честно говоря, меня это пугает!В конце концов, я прохожу трудности написания кода на C ++ / CLI, чтобы получить реальный нативный код, то есть сверхбыстрый машинный код x64.Однако это не похоже на значение по умолчанию для смешанных сборок .Пожалуйста, исправьте меня, если я ошибаюсь: если я использую значения по умолчанию проекта, заданные VC2017, моя сборка содержит MSIL, который будет JIT-скомпилирован.Верно?

Существует #pragma managed, который, кажется, препятствует генерации MSIL в пользу нативного кода для каждой функции.Я проверил это, и оно работает, но тогда проблема в том, что thunking снова мешает, как только нативный код вызывает управляемую функцию, и наоборот.В моем проекте C ++ / CLI я не нашел способа настроить thunking и генерацию кода без какого-либо снижения производительности.

Итак, что я сейчас задаю себе вопрос: какой смысл в использовании C ++ / CLIна первом месте?Это дает мне преимущества в производительности, когда все еще скомпилировано в MSIL?Может быть, лучше написать все на чистом C ++ и использовать Pinvoke для вызова этих функций?Я не знаю, я застрял здесь.

Может быть, кто-то может пролить свет на эту ужасно плохо документированную тему ...

...