Использование P / invoke для улучшения производительности, возможного или просто желаемого мышления? - PullRequest
3 голосов
/ 25 июля 2011

Это вопрос, который мне, вероятно, следовало бы задать раньше, но я не спешил веселиться с вещами типа p / invoke в MonoTouch.

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

Причиной этих операций является физический движок 2D, написанный на C #.

На некоторых платформах, таких как Windows Phone 7 и Xbox 360, физический движок работает без сбоев, он затягивает некоторые циклы ЦП, но оставляет достаточно, чтобы игра работала с постоянной частотой кадров.

Проблема в том, что MonoTouch работает на iPhone. Похоже, что MonoToch не так уж хорош с таким большим количеством операций с плавающей запятой, и iPhone (и даже iPad 2) оказываются под сильным влиянием, а физика является очевидным узким местом в производительности. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * *} хорошо написано, и я не вижу ни одного очевидного места, в котором он отстает, и, честно говоря, я сомневаюсь, что с ним как физическим движком 2D C # все в порядке.

С этой целью я решил найти физический движок, написанный на C (или C ++, если это возможно), и подключить его к основному приложению MonoTouch. Я рассуждаю так: проблемы с производительностью в MonoTouch, вероятно, имеют какое-то отношение к тому факту, что компилятор MonoTouch не компилирует .net-код для запуска так же быстро, как JIT-компиляторы Wp7 / xbox 360 (что понятно), что выводит вещи из режима монотушения. и запуск их в исходном режиме поможет улучшить производительность.

Так что моя идея заключается в том, что я буду использовать Box2D, напишу несколько статических функций-оболочек (таких как CreateWorld (), CreateBox (), GetBodyPosition (int id) и т. Д.) И подключу все это через p / вызовите функциональность и интегрируйте все это в мой класс-оболочку физики, таким образом, основная логика игры потребует минимальных изменений или вообще не требует изменений, и я могу поддерживать целостность оригинального проекта кода, но также повышать производительность благодаря тому факту, что физика работает в родной C.

Но это заставило меня задуматься, проблемы производительности возникают из-за очень простых и простых математических функций, простых умножений и сравнений размеров. Если запуск функций через p / invoke приведет к повышению скорости, то просто переписать такую ​​функцию, как Vector2.Max, как функцию C, и вызвать ее, что также улучшит производительность?

Это, однако, кажется немного надуманным, если бы это было так, разве Моно так не поступил бы?

Итак, я предполагаю, что мой общий вопрос заключается в том, работают ли статически связанные нативные библиотеки при вызове из p / invoke лучше, чем эквивалентная функция C #, скомпилированная MonoTouch?

Ответы [ 3 ]

3 голосов
/ 25 июля 2011

На самом деле есть только один способ выяснить, быстрее ли это: сравнить ваш случай. Может случиться так, что компилятор c, который вы будете использовать для нативной библиотеки, способен оптимизировать больше, чем jit моно, или это может быть просто процессор, который плохо подходит для вашей конкретной рабочей нагрузки.

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

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

2 голосов
/ 25 июля 2011

Если у вас есть некоторые критические разделы вашего кода, вы можете попробовать использовать «unsafe», чтобы избежать автоматической проверки диапазона для доступа к массиву. Для коротких массивов, таких как 2- или 3-векторы, и простых операций (например, норма или точечное произведение) это может иметь эффект.

Простые математические операции не должны быть медленнее, но трудно определить, какие части кода медленнее без профилирования результатов. Если собственная версия интенсивно использует sse или ваша управляемая версия непреднамеренно использует много коробок и т. Д., Это может привести к расхождению.

Чтобы P / invoke был полезен, вы должны сделать несколько вызовов, которые выполняют большую работу, поэтому может быть полезно, если вы можете обновить все состояние за один вызов для нативной dll. Но я бы не стал делать тривиальные функции родными.

1 голос
/ 26 июля 2011

В дополнение к отличному отклику Рольфа, вы можете рассмотреть возможность использования оптимизации LLVM при создании игры.

Меня удивляет, что Windows Phone 7 имеет лучшую JIT, чем статический компилятор Mono

...