Неоновые векторные инструкции сборки, влияющие на флаги

Я использую сборку руки и инструкции NEON SIMD. Я хочу получить максимум 16-битных значений без знака, которые находятся в двух регистрах Q, и сравнить их с порогом. Если все 16-битные значения меньше порогового значения, я вызываю функцию. Если одно или несколько значений больше порога, я вызываю другую функцию.

Следующие инструкции SIMD получают максимум.

// порог - это регистр r

vdup.16       q15, threshold  
vmax.u16      q12, q14, q13  
vcgt.u16      q11, q12, q15

Влияет ли vcgt на флаги FPSCR? Думаю, нет. Затем я должен проверить, равно ли q11 нулю или нет. Если это zeor, вызовите функцию1, иначе вызовите функцию2. Это было бы похоже

if (q11 == 0)
//call function1
else
//call function2 

Как я могу это сделать, не перемещая q11 в 4 регистра r?

Спасибо


person Ammar    schedule 13.06.2013    source источник


Ответы (1)


Их нет — по крайней мере, в пользовательском режиме. Эти инструкции cmp создают векторы маски, на основе которых вы выбираете значения между двумя результатами.

  1. создайте маску с соответствующим vcmp
  2. рассчитать результаты для обоих случаев
  3. используйте маску от 1, чтобы поместить соответствующие элементы в каждую дорожку из обоих результатов выше.

В настоящее время я не могу точно сказать вам, что это за инструкции, так как я пишу это на своем iPhone в поезде. Но найти их в справочнике не составит труда.

person Jake 'Alquimista' LEE    schedule 13.06.2013
comment
Я не хочу вычислять результаты для обоих случаев. Я хочу увеличить скорость своей программы, выбирая только один случай за раз на основе порога. Вот почему я разместил свой вопрос. Я найду другой способ. Спасибо, в любом случае. - person Ammar; 17.06.2013
comment
Я нашел другой способ, сузив значение в q13, а затем сравнив вектор с нулем. - person Ammar; 17.06.2013
comment
Вы должны избегать любых вызовов функций, пока NEON работает. Как только регистр ARM обращается к памяти (что БУДЕТ происходить при вызовах функций), это вызовет остановку конвейера, что обычно приводит к потере около 12 циклов. - person Jake 'Alquimista' LEE; 17.06.2013
comment
... Не говоря уже о том, что для каждого вызова функции вам (или вашему компилятору) также потребуется хранить все соответствующие регистры Q в стеке, чтобы избежать повреждения вызываемой функцией. Вот почему большинство ядер DSP являются листовыми функциями. Очень неэффективно делать то, что вы описываете. Проще сделать то, что предлагает Джейк, и просто встроить свою функцию. - person Peter M; 19.06.2013
comment
Другая идея для векторизации вашего алгоритма состоит в том, чтобы поместить результаты всех ваших сравнений в массив по существу логических значений. Когда функция возвращается, вызывающая функция может выполнить итерацию по массиву результатов и вызвать соответствующую подфункцию. - person Peter M; 19.06.2013
comment
Спасибо за ваши ответы, ребята. Вы абсолютно правы. Я использую макросы вместо вызовов функций. - person Ammar; 20.06.2013