Threading Box2D с резьбой - PullRequest
       15

Threading Box2D с резьбой

5 голосов
/ 02 марта 2012

Итак, я пытаюсь реализовать собственное расширение AIR, которое выполняет физическое моделирование в C с помощью интерфейсов через Actionscript.

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

В конечном счете, я ищу помощь в том, как мне настроить потоковую среду для запуска симуляции Box2D в отдельном потоке и последующего опроса состояния в AS3.

Методы:

  1. Грубая сила:

В этом методе я просто звоню в C из AS3 и говорю ему создать мир и передать ему несколько ящиков для добавления в этот мир. Каждый кадр в AS3 я вызываю в C, чтобы сообщить миру Step, затем перебираю все тела в Мире, определяю их положение и вращение, преобразую их в объекты actionscript и помещаю их в массив actionscript, а затем отправляю обратно AS3. Оказавшись там, я перебираю возвращаемый массив и назначаю эти значения положения и вращения моим спрайтам, чтобы они визуально обновлялись.

Результаты на самом деле вполне приличные: около 116 блоков добавляются до того, как ухудшится частота кадров. Это сравнивается с 30 блоками в чистой реализации AS3. Обратите внимание, что эта статистика в режиме отладки. В режиме выпуска они оба делают это приблизительно до 120 коробок. Существует небольшая разница между реализацией AS3 и реализацией собственного расширения.

  1. ByteArray Sharing

Чтобы улучшить производительность, я решил, что было бы неплохо попытаться ограничить объем данных, передаваемых через C и AS3. ANE поддерживает разделение пространства памяти байтового массива, и поэтому я бы отправил ByteArray, созданный в AS3, на C, а C просто обновил ByteArray. Это избавляет нас от необходимости создавать объекты AS3 в C и передавать их обратно. Каждый кадр AS3 просто должен пройти через свой ByteArray и посмотреть, что C записал в него, а затем присвоить эти значения спрайтам для установки визуального состояния.

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

  1. Прямая установка объекта из C

Другая вещь, на которую способны ANE, - это установка свойства объекта, который живет в AS3. В этом смысле я стремился устранить издержки, связанные с передачей данных в AS3, циклически проходя через тела для сбора данных в C и проходя через AS3 для назначения значений. Я напрямую изменил код Box2D, чтобы при изменении его значений записывать новые значения вращения x, y, непосредственно на соответствующий Sprite.

Результаты удивительны при очень небольшом количестве объектов, так как вызов для установки этих свойств длится менее миллисекунды. Проблема в том, что это линейно масштабируется и составляет около 90 или около того объектов, чрезмерные накладные расходы и вещи начинают замедляться.

  1. Threading

В этот момент я был немного озадачен. В процессе сортировки данных есть издержки, в C есть затраты на итерацию и создание возвращаемых данных, а в AS3 - на итерацию для присвоения значений спрайтам.

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

На стороне AS3 вы звоните в C, чтобы создать свой мир, звоните, чтобы добавить ящик в этот мир, и звоните, чтобы сказать C, что вы хотите обновить свои данные. Когда ящики создаются в AS3, они получают уникальный идентификатор и сохраняются в словаре, а ключ является идентификатором.

Со стороны C, мир создан, и появляется новый поток, чтобы выполнить Шаг. По сути, имитирующий мир в другом потоке. После этого он собирает все данные и записывает их в двойной массив. Затем он делает это снова и снова и снова. Он просто симулирует навсегда в своей собственной нити.

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

То же самое, когда мы вызываем для обновления значений в AIR, я хочу сделать memcpy из массива double в мой байтовый массив AS3, а затем перебрать байтовый массив для установки значений в визуале.

Мьютексы доставляли мне неприятности, поэтому я в основном реализовал свой собственный, который вы можете увидеть ниже ... и посмеялся:)

Однако это работает, но не так быстро, как хотелось бы. Около 90 мы снова замедлились.

У кого-нибудь есть мысли или указатели? Это будет с благодарностью!

C Код

Парсер работал, поэтому я вставил его здесь: http://pastebin.com/eBQGuGJX

Код AS3

То же самое с парсером. Я включил только соответствующий метод, имеющий дело с каждым кадром в AS3. http://pastebin.com/R1Qs2Tyt

1 Ответ

3 голосов
/ 18 апреля 2012

Я забыл, у меня был этот вопрос.К счастью, я понял это.

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

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

Итак, что происходит сейчас, когда Клиент вызывает ANE для настройки мира, он создает новыйнить, которая имитирует мир и сразу возвращается обратно во Flash.Flash продолжит выполнять свою работу, выполняя остальную часть клиентского кода, а затем рендеринг, а затем GC.

Затем в каждом кадре во Flash мы можем просто вызвать ANE для получения результатов.В случае, если поток Simulation не был закончен, мы ждем через соединение, извлекаем значения и возвращаем их во Flash.Обязательно создайте другой поток для следующего шага, прежде чем возвращать, конечно.

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

Хорошая новость заключается в том, что при таком подходе производительность почти удваивается.Переход от приблизительно 90 блоков в синхронной реализации чистого AS3 к приблизительно 170 блокам в многопоточном подходе ANE.

Узким местом в конечном итоге становится итерация по данным, возвращающимся из ANE, и присвоение этих значений экранным объектам.

Надеюсь, это поможет кому-то еще, кто искал что-то подобное.Я выступлю с докладом на FITC в Торонто в конце апреля, так что тогда я смогу опубликовать больше информации и материалов.

http://www.fitc.ca/events/presentations/presentation.cfm?event=124&presentation_id=1973

...