Проблемы с двухъядерным кодом ARM NEON компании Qualcomm Scorpion? - PullRequest
6 голосов
/ 29 сентября 2011

Я разрабатываю собственную библиотеку для Android, в которой я использую оптимизацию сборок ARM и многопоточность, чтобы добиться максимальной производительности на двухъядерном чипсете ARM MSM8660.Выполняя некоторые измерения, я заметил следующее:

  1. Однопоточная библиотека с NEON оптимизацией на быстрее , чем однопотоковая библиотека с ARMv6 оптимизацией (как и ожидалось).
  2. многопоточная библиотека с ARMv6 оптимизацией равна *На 1020 * быстрее , чем однопоточная библиотека с ARMv6 оптимизацией (как и ожидалось).
  3. многопоточная библиотека с NEON оптимизаций * на 1032 * медленнее , чем однопоточная библиотека с NEON оптимизациями (определенно не ожидается!).

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

Ответы [ 3 ]

1 голос
/ 05 августа 2012

Прежде всего, какую библиотеку вы используете?

Вы правы, каждое ядро ​​имеет свой собственный блок NEON, однако это собственный проприетарный блок VeNum, и о нем не предоставлено много информации. Он был разработан для Scorpion на базе Cortex-A8 в 8x50 и был довольно лучше, чем собственная реализация ARM NEON SIMD, однако хорошее облегчение состоит в том, что они (qcom) проектируют свое оборудование таким образом, чтобы оно было совместимо с базовым дизайном refrence, поэтому большая часть кода для cortex-A8 будет отлично работать с Scorpion, хотя и с некоторыми снижение производительности из-за возможного различного времени выполнения команд.

Если вы используете "softfp" для компиляции вашей программы, у вас будет около 20 циклов для каждой вызываемой вами функции, которая использует аргументы с плавающей запятой или использует блок NEON для передачи данных регистра из ядра ARM в Неоновый блок и наоборот довольно медленный и иногда может останавливать ядро ​​на много циклов, ожидая сброса трубопровода.

Также для многопоточной программы, использующей модуль с плавающей запятой, ядро ​​должно сохранять регистры FP во время переключения контекста, что влечет за собой дополнительные потери для потоков, так как мы уже знаем, что перемещение регистров от неона к руке медленное и известно, что оно останавливает трубопровод.

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

0 голосов
/ 25 ноября 2011

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

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

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

0 голосов
/ 02 октября 2011

Это, вероятно, из-за отсутствия кэша. Трудно сказать без дополнительной информации.

...