Я использую вариант 5-перекрестного медианного фильтра для данных изображения в небольшой встроенной системе, т.е.
x
x x x
x
Алгоритм действительно прост: прочитайте 5 целочисленных значений без знака, получите самые высокие 2, сделайте некоторые вычисления и запишите результат целого числа без знака.
Что приятно, так это то, что все 5 целочисленных входных значений находятся в диапазоне 0-20. Рассчитанное целочисленное значение также находится в диапазоне 0-20!
Благодаря профилированию я понял, что получение двух самых больших чисел является узким местом, поэтому я хочу ускорить эту часть. Какой самый быстрый способ выполнить этот выбор?
Текущий алгоритм использует 32-битную маску с 1 в позиции, заданной 5 числами, и поддерживаемую HW функцию CLZ.
Я должен сказать, что процессор является проприетарным и недоступен за пределами моей компании. Мой компилятор GCC, но специально для этого процессора.
Я попытался выяснить, могу ли я использовать справочную таблицу, но мне не удалось сгенерировать ключ, который я могу использовать.
У меня есть комбинаций для ввода, но порядок не важен, то есть такой же, как .[5,0,0,0,5]
[5,5,0,0,0]
Бывает, что приведенная ниже хеш-функция создает идеальный хеш без коллизий!
def hash(x):
h = 0
for i in x:
h = 33*h+i
return h
Но хэш огромен, и для его использования просто недостаточно памяти.
Есть ли лучший алгоритм, который я могу использовать? Можно ли решить мою проблему с помощью таблицы соответствия и генерации ключа?
источник
hash
уже выполняет больше операций. Связаны ли последующие вызовы метода, например, центральныйx
линг пересекает матрицу построчно?Ответы:
В моем другом ответе я предполагаю, что условные скачки могут быть основным препятствием для эффективности. Как следствие, на ум приходят сети сортировки : они независимы от данных, то есть одна и та же последовательность сравнений выполняется независимо от ввода, только условные свопы.
Сеть, которую он дает в решениях (переписанная в нулевые массивы)
который реализует - после корректировки направления сравнений - в псевдокоде как
Теперь наивные реализации все еще имеют условные переходы (через код подкачки). В зависимости от вашей машины вы можете обойти их условными инструкциями. x86, кажется, обычная грязь; ARM выглядит более перспективным, так как, по-видимому, большинство операций являются условными сами по себе. Если я правильно понимаю инструкции , первый своп преобразуется в это, предполагая, что наши значения массива были загружены в регистры
R0
черезR4
:Да, да, конечно, вы можете использовать обмен XOR с EOR .
Я просто надеюсь, что ваш процессор имеет это, или что-то подобное. Конечно, если вы создадите это для этой цели, может быть, вы сможете подключить туда сеть?
Это, вероятно (доказуемо?) Лучшее, что вы можете сделать в классической сфере, то есть, не используя ограниченную область и не применяя злые внутрисловные фокусы.
источник
Просто для того, чтобы это было на столе, вот прямой алгоритм:
С помощью умной реализации
if ... else
можно избавиться от некоторых безусловных переходов, которые имел бы прямой перевод.Это некрасиво, но занимает только
Однако нельзя ожидать, что это будет быстрым на машинах с конвейерной обработкой; учитывая высокий процент условных скачков, большая часть времени, вероятно, будет проведена в стойле.
Обратите внимание, что более простой вариант - сортировка
x1
иx2
последующая вставка других значений - требует от четырех до семи сравнений и только от пяти до шести назначений. Так как я ожидаю, что прыжки здесь будут дороже, я остановился на этом.источник
Это может быть отличным приложением и тестовым примером для проекта Souper . Souper - это супероптимизатор - инструмент, который принимает короткую последовательность кода в качестве входных данных и пытается максимально оптимизировать ее (пытается найти эквивалентную последовательность кода, которая будет быстрее).
Souper с открытым исходным кодом. Вы можете попробовать запустить Souper в своем фрагменте кода, чтобы посмотреть, сможет ли он работать лучше.
Смотрите также конкурс Джона Регера на написание быстрого кода для сортировки 16 4-битных значений ; Возможно, что некоторые из техник там могут быть полезны.
источник
T[T[T[441*a+21*b+c]*21+d]*21+e]
источник