Математические функции занимают больше циклов после запуска любой функции Intel AVX

Я заметил, что математические функции (такие как ceil, round и т. д.) занимают больше циклов ЦП после запуска любой функции Intel AVX.

См. следующий пример:

#include <stdio.h>
#include <math.h>
#include <immintrin.h>


static unsigned long int get_rdtsc(void)
{
        unsigned int a, d;
        asm volatile("rdtsc" : "=a" (a), "=d" (d));
        return (((unsigned long int)a) | (((unsigned long int)d) << 32));
}

#define NUM_ITERATIONS 10000000

void run_round()
{
    unsigned long int t1, t2, res, i;
    double d = 3.2;

    t1 = get_rdtsc();
    for (i = 0 ; i < NUM_ITERATIONS ; ++i) {
        res = round(d*i);
    }
    t2 = get_rdtsc();

    printf("round res %lu total cycles %lu CPI %lu\n", res, t2 - t1, (t2 - t1) / NUM_ITERATIONS);
 }

int main ()
{
    __m256d a;

    run_round();

    a = _mm256_set1_pd(1);

    run_round();

    return 0;
}

скомпилировать с помощью: gcc -Wall -lm -mavx foo.c

Результат:

круглое разрешение 31999997 всего циклов 224725952 CPI 22

круглое разрешение 31999997 всего циклов 1900864520 CPI 190

Пожалуйста, порекомендуйте.


person kayan4096    schedule 12.12.2013    source источник
comment
Какая целевая платформа? Linux, OS X, что-то еще?   -  person Eric Postpischil    schedule 12.12.2013
comment
Спасибо @StephenCanon за добавление __asm(VZEROUPPER) после вызова avx. Однако мне интересно, не является ли это ошибкой в ​​​​gcc - один вызов встроенной функции avx добавляет производительности ко всем вызовам устаревшей библиотеки, если регистр YMM не очищен?   -  person kayan4096    schedule 12.12.2013
comment
@ kayan4096: Я удивлен, что GCC не вставляет для вас vzeroupper; кланг делает это.   -  person Stephen Canon    schedule 12.12.2013
comment
Вероятно, стоит отправить отчет об ошибке разработчикам GCC, чтобы попросить их сделать это.   -  person Stephen Canon    schedule 12.12.2013
comment
@StephenCanon, ваши комментарии здесь помогли мне решить следующий вопрос stackoverflow.com/questions/21960229/.   -  person Z boson    schedule 24.02.2014
comment
@StephenCanon, GCC не делает этого по умолчанию, как Clang, но у него есть опция -mvzeroupper, которая сделает это.   -  person Z boson    schedule 30.06.2014


Ответы (1)


Разберите сгенерированный код.

Я предполагаю, что происходит дополнительное сохранение/восстановление регистра или что-то в этом роде.

person unwind    schedule 12.12.2013
comment
Нет никакой разницы в версии Apple GCC; run_round вызывается в двух местах из main, поэтому внутри подпрограммы выполняются идентичные инструкции. Я ожидал бы того же и в других версиях GCC. - person Eric Postpischil; 12.12.2013