Какой самый быстрый способ получить значение π?



Я ищу самый быстрый способ получить значение π, как личный вызов. Более конкретно, я использую способы, которые не связаны с использованием #define константы как M_PI, или жесткого кодирования в количество.



программа ниже проверяет различные способы, которые я знаю. Встроенная версия сборки, в теории, самый быстрый вариант, хотя и не портативный. Я включил его в качестве базового для сравнения с другими версиями. В моих тестах, со встроенными,4 * atan(1) версия является самым быстрым на GCC 4.2, потому что он автоматически складывает atan(1) в постоянное. С -fno-builtin указано,atan2(0, -1) версия является самым быстрым.



вот основная программа тестирования (pitimes.c):



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

#define ITERS 10000000
#define TESTWITH(x) {
diff = 0.0;
time1 = clock();
for (i = 0; i < ITERS; ++i)
diff += (x) - M_PI;
time2 = clock();
printf("%st=> %e, time => %fn", #x, diff, diffclock(time2, time1));
}

static inline double
diffclock(clock_t time1, clock_t time0)
{
return (double) (time1 - time0) / CLOCKS_PER_SEC;
}

int
main()
{
int i;
clock_t time1, time2;
double diff;

/* Warmup. The atan2 case catches GCC's atan folding (which would
* optimise the ``4 * atan(1) - M_PI'' to a no-op), if -fno-builtin
* is not used. */
TESTWITH(4 * atan(1))
TESTWITH(4 * atan2(1, 1))

#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__))
extern double fldpi();
TESTWITH(fldpi())
#endif

/* Actual tests start here. */
TESTWITH(atan2(0, -1))
TESTWITH(acos(-1))
TESTWITH(2 * asin(1))
TESTWITH(4 * atan2(1, 1))
TESTWITH(4 * atan(1))

return 0;
}


и встроенный материал сборки (fldpi.c) это будет работать только для x86 и x64 систем:



double
fldpi()
{
double pi;
asm("fldpi" : "=t" (pi));
return pi;
}


и скрипт сборки, который строит все конфигурации, которые я тестирую (build.sh):



#!/bin/sh
gcc -O3 -Wall -c -m32 -o fldpi-32.o fldpi.c
gcc -O3 -Wall -c -m64 -o fldpi-64.o fldpi.c

gcc -O3 -Wall -ffast-math -m32 -o pitimes1-32 pitimes.c fldpi-32.o
gcc -O3 -Wall -m32 -o pitimes2-32 pitimes.c fldpi-32.o -lm
gcc -O3 -Wall -fno-builtin -m32 -o pitimes3-32 pitimes.c fldpi-32.o -lm
gcc -O3 -Wall -ffast-math -m64 -o pitimes1-64 pitimes.c fldpi-64.o -lm
gcc -O3 -Wall -m64 -o pitimes2-64 pitimes.c fldpi-64.o -lm
gcc -O3 -Wall -fno-builtin -m64 -o pitimes3-64 pitimes.c fldpi-64.o -lm


отдельно от испытывать между различным флаги компилятора (я также сравнивал 32-разрядные с 64-разрядными, потому что оптимизация отличается), я также попытался переключить порядок тестов. Но все же,atan2(0, -1) версия по-прежнему выходит на первое место каждый раз.

653   0  

Comments

    Ничего не найдено.