double hypot(double x, double y);hypot() 函数返回 sqrt(x*x+y*y)。 如果成功,该函数将返回一个直角三角形,两个直角边的长度分别是 x 和 y。如果 x 或 y 是无穷大,则返回正无穷大。如果 x 或 y 为 NaN,而另一个参数不是无穷大,则返回 NaN。如果结果溢出,就会发生一个范围错误,该函数会分别返回 HUGE_VAL、HUGE_VALF 或 HUGE_VALL。如果两个参数都异常,结果也是异常的,并且发现范围错误,则返回正确的结果。该算法虽然看似简单,能够处理 Infinity 和 NaN 的 Floating-Point (FP) 参数,以及与 FP 有关的溢出/下溢,但它对性能影响增加了一些挑战。GNU C Library提供一个位于 sysdeps/ieee754/dbl-64/e_hypot.c 源树中的 hypot 实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | double __ieee754_hypot(double x, double y) { double a,b,t1,t2,y1,y2,w; int32_t j,k,ha,hb; GET_HIGH_WORD(ha,x); ha &= 0x7fffffff; GET_HIGH_WORD(hb,y); hb &= 0x7fffffff; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} SET_HIGH_WORD(a,ha); /* a <- |a| */ SET_HIGH_WORD(b,hb); /* b <- |b| */ if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */ k=0; if(ha > 0x5f300000) { /* a>2**500 */ if(ha >= 0x7ff00000) { /* Inf or NaN */ u_int32_t low; w = a+b; /* for sNaN */ GET_LOW_WORD(low,a); if(((ha&0xfffff)|low)==0) w = a; GET_LOW_WORD(low,b); if(((hb^0x7ff00000)|low)==0) w = b; return w; } /* scale a and b by 2**-600 */ ha -= 0x25800000; hb -= 0x25800000; k += 600; SET_HIGH_WORD(a,ha); SET_HIGH_WORD(b,hb); } if(hb < 0x20b00000) { /* b < 2**-500 */ if(hb <= 0x000fffff) { /* subnormal b or 0 */ u_int32_t low; GET_LOW_WORD(low,b); if((hb|low)==0) return a; t1=0; SET_HIGH_WORD(t1,0x7fd00000); /* t1=2^1022 */ b *= t1; a *= t1; k -= 1022; } else { /* scale a and b by 2^600 */ ha += 0x25800000; /* a *= 2^600 */ hb += 0x25800000; /* b *= 2^600 */ k -= 600; SET_HIGH_WORD(a,ha); SET_HIGH_WORD(b,hb); } } /* medium size a and b */ w = a-b; if (w>b) { t1 = 0; SET_HIGH_WORD(t1,ha); t2 = a-t1; w = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; y1 = 0; SET_HIGH_WORD(y1,hb); y2 = b - y1; t1 = 0; SET_HIGH_WORD(t1,ha+0x00100000); t2 = a - t1; w = __ieee754_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { u_int32_t high; t1 = 1.0; GET_HIGH_WORD(high,t1); SET_HIGH_WORD(t1,high+(k<<20)); return t1*w; } else return w; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | CPI Breakdown Model (Complete) Metric : Value : Percent PM_CMPLU_STALL_DIV : 8921688.0 : 8.7 PM_CMPLU_STALL_FXU_OTHER : 13953382275.0 : 5.0 PM_CMPLU_STALL_SCALAR_LONG : 24380128688.0 : 8.7 PM_CMPLU_STALL_SCALAR_OTHER : 33862492798.0 : 12.0 PM_CMPLU_STALL_VECTOR_LONG : 0.0 : 0.0 PM_CMPLU_STALL_VECTOR_OTHER : 275057010.0 : 0.1 PM_CMPLU_STALL_ERAT_MISS : 173439.0 : 0.0 PM_CMPLU_STALL_REJECT_OTHER : 902838.0 : 0.0 PM_CMPLU_STALL_DCACHE_MISS : 15200163.0 : 0.0 PM_CMPLU_STALL_STORE : 1837414.0 : 0.0 PM_CMPLU_STALL_LSU_OTHER : 94866270200.0 : 33.7 PM_CMPLU_STALL_THRD : 569036.0 : 0.0 PM_CMPLU_STALL_BRU : 10470012464.0 : 3.7 PM_CMPLU_STALL_IFU_OTHER : -73357562.0 : 0.0 PM_CMPLU_STALL_OTHER : 7140295432.0 : 2.5 PM_GCT_NOSLOT_IC_MISS : 3586554.0 : 0.0 PM_GCT_NOSLOT_BR_MPRED : 1008950510.0 : 0.4 PM_GCT_NOSLOT_BR_MPRED_IC_MISS : 795943.0 : 0.0 PM_GCT_EMPTY_OTHER : 42488384303.0 : 15.1 PM_1PLUS_PPC_CMPL : 53138626513.0 : 18.9 OVERHEAD_EXPANSION : 30852715.0 : 0.0 Total : 108.7 |
1 2 3 4 5 6 | $ perf record -C 0 -e rc8ac taskset -c 0 ./hypot_bench_glibc $ perf report Events: 14K raw 0xc8ac 79.19% hypot_bench_gli libm-2.12.so [.] __ieee754_hypot 10.38% hypot_bench_gli libm-2.12.so [.] __hypot 6.34% hypot_bench_gli libm-2.12.so [.] __GI___finite |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | : 00000080fc38b730 <.__ieee754_hypot>: 0.00 : 80fc38b730: 7c 08 02 a6 mflr r0 0.00 : 80fc38b734: fb c1 ff f0 std r30,-16(r1) 0.00 : 80fc38b738: fb e1 ff f8 std r31,-8(r1) 13.62 : 80fc38b73c: f8 01 00 10 std r0,16(r1) 0.00 : 80fc38b740: f8 21 ff 71 stdu r1,-144(r1) 10.82 : 80fc38b744: d8 21 00 70 stfd f1,112(r1) 0.23 : 80fc38b748: e9 21 00 70 ld r9,112(r1) 17.54 : 80fc38b74c: d8 41 00 70 stfd f2,112(r1) 0.00 : 80fc38b750: 79 29 00 62 rldicl r9,r9,32,33 0.00 : 80fc38b754: e9 61 00 70 ld r11,112(r1) 0.00 : 80fc38b758: e8 01 00 70 ld r0,112(r1) 8.46 : 80fc38b75c: d8 21 00 70 stfd f1,112(r1) [...] |
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |