मैं व्यक्तिगत चुनौती के रूप में as का मान प्राप्त करने का सबसे तेज़ तरीका खोज रहा हूं। अधिक विशेष रूप से, मैं ऐसे तरीकों का उपयोग कर रहा हूं, जिनमें #define
निरंतरता का उपयोग करना शामिल नहीं है M_PI
, या संख्या को हार्ड-कोडिंग करना शामिल है।
नीचे दिया गया कार्यक्रम उन विभिन्न तरीकों का परीक्षण करता है जिनके बारे में मुझे पता है। इनलाइन असेंबली संस्करण, सिद्धांत रूप में, सबसे तेज़ विकल्प है, हालांकि स्पष्ट रूप से पोर्टेबल नहीं है। मैंने इसे अन्य संस्करणों के मुकाबले तुलना करने के लिए आधार रेखा के रूप में शामिल किया है। बिल्ट-इन के साथ मेरे परीक्षणों में, 4 * atan(1)
संस्करण जीसीसी 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("%s\t=> %e, time => %f\n", #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
विभिन्न संकलक झंडों के बीच परीक्षण के अलावा (मैंने 64-बिट के मुकाबले 32-बिट की तुलना की है, क्योंकि अनुकूलन अलग-अलग हैं), मैंने परीक्षणों के क्रम को बदलने की भी कोशिश की है। लेकिन फिर भी, atan2(0, -1)
संस्करण अभी भी हर बार शीर्ष पर आता है।