Параллельность с OpenGL ES + CoreData - PullRequest
2 голосов
/ 09 сентября 2011

У меня три задания:

  1. Задача извлечения. Он извлекает объекты (около 2000 из них) из CoreData и передает NSManagedObjectIDs в основной поток, где они преобразуются обратно в NSManagedObjects и сохраняются в NSArray. Эта задача имеет наименьший приоритет.

  2. Вычислительная задача. Эта задача перебирает эти объекты и вычисляет некоторые значения для объекта. Значения хранятся как временные атрибуты подкласса NSManagedObject. Эта задача имеет 2-й наивысший приоритет.

  3. Задача рисования OpenGL ES. Это цикл рисования, который обновляет пользовательский интерфейс на основе результата вычислительной задачи. Эта задача имеет наивысший приоритет, так как любое замедление уменьшит частоту кадров и будет очень заметным при масштабировании или панорамировании.

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

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

Ответы [ 2 ]

2 голосов
/ 10 сентября 2011

Я думаю, что лучшим решением является следующее.

  • Выполнить задачи 1 и 2 в параллельных или последовательных очередях GCD. Используйте параллельные очереди GCD для одновременных выполнимых задач.
  • Выполнить задачу 3 в главном RunLoop.

Пожалуйста, обратитесь к документу « Руководство по программированию OpenGL ES для iOS - параллелизм и OpenGL ES »

Определение того, может ли приложение OpenGL извлечь выгоду из параллелизма

Приложение выполняет много задач на CPU, которые не зависят от рендеринга OpenGL ES. Например, игры имитируют игровой мир, вычисляют искусственный интеллект от компьютерных противников и воспроизводят звук. Вы можете использовать параллелизм в этом сценарии, потому что многие из этих задач не зависят от вашего кода рисования OpenGL ES.

Тем не менее, если вам нужно использовать многопоточный рендеринг OpenGL ES, эти полезные документы могут вам помочь.

1 голос
/ 13 сентября 2011

Для тех, кто найдет эту ветку на более позднем этапе, вот как я в итоге решил проблему:

  • Задача извлечения выполняется в своей собственной очереди GCD и извлекает объекты NSManagedObject из CoreData. Я создал новый класс, который содержит вычисленные свойства для каждого из моих объектов. Используя извлеченные данные, я создал экземпляр NSArray этих объектов и передал их в задачу вычисления, отправив операцию блока в очередь вычислений.

  • Задача вычисления выполняется в своей собственной очереди GCD и вычисляет значения для каждого из этих объектов каждую секунду или две. После завершения он передает NSArray в очередь рисования, отправляя блок в очередь рисования.

  • Задача рисования выполняется в своей собственной очереди GCD и является асинхронной. Все, что он делает, это перебирает объекты и рисует их.

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

...