макс. x86 / минута asm инструкции?

Есть ли какие-либо asm инструкции, которые могут ускорить вычисление минуты / макс. из вектора удваивается/целым числа на архитектуре Core i7?

Обновление:

Я не ожидал такие богатые ответы, спасибо. Таким образом, я вижу, что макс. / минута возможно обойтись без ветвления. У меня есть дополнительный вопрос:

Существует ли эффективный способ получить индекс самого большого дважды в массиве?

8
задан OMG Ponies 5 July 2011 в 03:39
поделиться

4 ответа

SSE4 имеет PMAXSD или PMAXUD для 32-битных подписанных/неподписанных целых чисел, что может быть полезно.

SSE2 имеет MAXPD и MAXSD, которые сравнивают между собой и попарно пары двойников, поэтому вы следуете за n/2-1 MAXPD с одним MAXSD, чтобы получить максимум вектора n, с обычным чередованием нагрузок и операций.

Существуют МИН-эквиваленты вышеперечисленного.

Для двойного случая в ассемблере, скорее всего, не будет лучше, чем полуприличный компилятор C++ в режиме SSE:

peregrino:$ g++ -O3 src/min_max.cpp -o bin/min_max
peregrino:$ g++ -O3 -msse4 -mfpmath=sse src/min_max.cpp -o bin/min_max_sse
peregrino:$ time bin/min_max
0,40

real    0m0.874s
user    0m0.796s
sys 0m0.004s
peregrino:$ time bin/min_max_sse 
0,40

real    0m0.457s
user    0m0.404s
sys 0m0.000s

где min_max вычисляет min и max массива из 500 удваивается 100,000 раз, используя наивный цикл:

bool min_max ( double array[], size_t len, double& min, double& max )
{
    double min_value = array [ 0 ];
    double max_value = array [ 0 ];

    for ( size_t index = 1; index < len; ++index ) {
        if ( array [ index ] < min_value ) min_value = array [ index ];
        if ( array [ index ] > max_value ) max_value = array [ index ];
    }

    min = min_value;
    max = max_value;
}

В ответ на вторую часть, традиционная оптимизация для удаления ветвления от максимальной операции заключается в сравнении значений, получении флага в виде одного бита ( давая 0 или 1 ), вычитании одного ( давая 0 или 0xffff_ffff ) и 'и' его с xor из двух возможных результатов, так что вы получаете эквивалент ( a > best ? ( current_index ^ best_index ) : 0 ) ^ best_index ). Я сомневаюсь, что есть простой SSE способ сделать это, просто потому что SSE имеет тенденцию работать с упакованными значениями, а не с помеченными значениями; есть некоторые горизонтальные операции с индексами, так что вы можете попробовать найти max, затем вычесть его из всех элементов в исходном векторе, затем собрать знаковый бит, и нулевой знак будет соответствовать индексу max, но это, вероятно, не было бы улучшением, если бы вы не использовали шорты или байты.

12
ответ дан 5 December 2019 в 08:24
поделиться

MAXPS и MINPS из SSE работают с упакованными одноточными номерами с плавающей точкой. PMAXSW, PMINSW, PMAXUB и PMINUB работают с упакованными 8-битными словами, как подписанными, так и неподписанными. Обратите внимание, что они сравнивают два входных SSE регистра или адресные места по элементам и сохраняют результат в SSE регистре или памяти.

SSE2 версии MAXPS и MINPS должны работать с плавающими числами двойной точности.

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

4
ответ дан 5 December 2019 в 08:24
поделиться

если Вы используете библиотеку Intel IPP, то можете использовать векторные статистические функции для вычисления векторного min/max (среди прочего)

.
2
ответ дан 5 December 2019 в 08:24
поделиться

В ответ на Ваш второй вопрос: на большинстве платформ существуют библиотеки, которые уже содержат оптимизированные реализации именно этой операции (и большинства других простых векторных операций). Используйте их.

  • На операционной системе X в ускорителе есть vDSP_maxviD( ) и cblas_idamax( ). framework
  • Компиляторы Intel включают в себя библиотеки IPP и MKL, которые имеют высокопроизводительные реализации, в том числе cblas_idamax( )
  • Большинство систем Linux будут иметь в библиотеке BLAS cblas_idamax( ), которые в зависимости от их происхождения могут быть хорошо настроены, а могут и не быть; Пользователи, которым небезразлична производительность, как правило, имеют хорошую реализацию (или их можно убедить установить)
  • Если все остальное не удастся, можно использовать ATLAS (Automatically Tuned Linear Algebra Software), чтобы получить приличную производительность реализации на целевой платформе
2
ответ дан 5 December 2019 в 08:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: