[#352] ruby 1.1a5 released — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

38 messages 1997/09/01
[#353] Re: ruby 1.1a5 released — keiju@... (石塚圭樹 ) 1997/09/01

[#354] Re: ruby 1.1a5 released — matz@... (Yukihiro Matsumoto) 1997/09/01

まつもと ゆきひろです

[#356] Re: methods [Re: ruby 1.1a5 released] — matz@... (Yukihiro Matsumoto) 1997/09/01

まつもと ゆきひろです

[#357] Re: methods [Re: ruby 1.1a5 released] — keiju@... (Keiju ISHITSUKA) 1997/09/01

けいじゅ@日本ラショナルソフトウェアです.

[#359] Re: methods [Re: ruby 1.1a5 released] — matz@... (Yukihiro Matsumoto) 1997/09/02

まつもと ゆきひろです

[#363] Re: methods [Re: ruby 1.1a5 released] — matz@... (Yukihiro Matsumoto) 1997/09/02

まつもと ゆきひろです

[#374] Re: methods [Re: ruby 1.1a5 released] — matz@... (Yukihiro Matsumoto) 1997/09/02

まつもと ゆきひろです

[#376] Re: methods [Re: ruby 1.1a5 released] — keiju@... (Keiju ISHITSUKA) 1997/09/02

けいじゅ@日本ラショナルソフトウェアです.

[#382] Re: methods [Re: ruby 1.1a5 released] — matz@... (Yukihiro Matsumoto) 1997/09/02

まつもと ゆきひろです

[#390] Re: methods [Re: ruby 1.1a5 released] — keiju@... (Keiju ISHITSUKA) 1997/09/03

けいじゅ@日本ラショナルソフトウェアです.

[#391] Re: methods [Re: ruby 1.1a5 released] — matz@... (Yukihiro Matsumoto) 1997/09/03

まつもと ゆきひろです

[#441] How to report a bug — takagi@... (TAKAGI Hiromitsu)

Bus error が出ました。

15 messages 1997/09/09

[#461] [Q] ruby-socket(mswin32) — Masaki Suketa <suke@...>

助田です

27 messages 1997/09/11
[#462] Re: [Q] ruby-socket(mswin32) — matz@... (Yukihiro Matsumoto) 1997/09/11

まつもと ゆきひろです

[#463] Re: [Q] ruby-socket(mswin32) — Masaki Suketa <suke@...> 1997/09/11

助田です

[#464] Re: [Q] ruby-socket(mswin32) — matz@... (Yukihiro Matsumoto) 1997/09/11

まつもと ゆきひろです

[#467] Re: [Q] ruby-socket(mswin32) — WATANABE Hirofumi <watanabe@...> 1997/09/11

わたなべです.

[#594] BUG?(marshal) — Masaki Suketa <suke@...>

以下のプログラムを実行した時に(3)と(4)で出力結果が違います。

17 messages 1997/09/30

[ruby-dev:546] Re: optimize (Re: Assigne to special variable)

From: "EGUCHI Osamu" <eguchi@...>
Date: 1997-09-26 08:40:40 UTC
List: ruby-dev #546
えぐち です

----------
> 件名 : [ruby-dev:537] Re: optimize (Re: Assigne to special variable)
> 
> まつもと ゆきひろです

> |まったく別の場所では、Bignum の四則や比較といった重いところを、
> |「if 文の算術式化」などで、少しチューニング出来そうな気がします。
> 
> これ,具体的にはどんなのでしょう?

仮パッチつけました。

bigsub()
	+ ループの底の if を同義の演算に変形
	  パイプラインのストールを防ぐため
	+ 減数をひき切った後は純コピーループに移る
	  桁上がりの監視で簡単に判別可能です

bigadd()
	+ リザルトの0クリアを省略
	+ 全加算→桁上がのみ→純コピーの順に変形
	  桁数の比較で順序を整合できます

binmul()
	+ ループの底の if を同義の演算に変形
	+ 不要なメモリ(配列要素)への書き戻しの除去	

bigdivmod()
	+ 桁数一致時も最上位桁の比較で分子<分母検知
	  これ以上深入りして比較するとコストアップ
	+ ループの底の if を同義の演算に変形
	+ 不要なメモリ(配列要素)への書き戻しの除去	

sample/pi.rb の外周の while TRUE を for i in 1..1000
とかにすると、約倍速になったことがわかります。
演算の比率や数値の大きさにより効果が異なると思います。

あと、Bignum の sizeof(*digits) を2から4にすると
倍以上速くなるのはわかっているのですが、
	影響で動かなくなるコードが多い
ので見送った方がいいです。

#
昔々アセンブラやマイクロコードでライブラリかいてたときに
こんな事ばっかりしてたです。
いまの RISC や Pentium って剥き出しのパイプラインを
意識するとむちゃむちゃ速くなる事があるんです。
#うぅん、、思いっきり低水準だ!

まだ、テストが完全ぢゃないのでマージしないでください。
#この手のテストってやっかいですよね。

#新旧両方の演算ルーチンをもって ruby を作って比較しながら
#走らせるとか、、比較が腐ってたりして、、

以下、そのパッチです。

--- ../ruby-1.0-970919/bignum.c	Tue Jun  3 15:27:01 1997
+++ bignum.c	Thu Sep 25 11:41:41 1997
@@ -9,6 +9,7 @@
 ************************************************/
 
 #include "ruby.h"
+#include <stdio.h>
 #include <ctype.h>
 #include <math.h>
 
@@ -503,35 +504,20 @@ bigsub(x, y)
     z = (struct RBignum*)bignew(x->len, (z == 0)?1:0);
     zds = BDIGITS(z);
 
-    i = x->len;
-    while (i--) zds[i] = BDIGITS(x)[i];
-
-    i = 0; num = 0;
-    do {
-	num += (long)zds[i] - BDIGITS(y)[i];
-	if (num < 0) {
-	    zds[i] = num + BIGRAD;
-	    num = -1;
-	}
-	else {
-	    zds[i] = BIGLO(num);
-	    num = 0;
-	}
-    } while (++i < y->len);
-    if (num) {
-	while (num && i < x->len) {
-	    num += zds[i];
-	    if (num < 0) {
-		zds[i++] = num + BIGRAD;
-		num = -1;
-	    }
-	    else {
-		zds[i++] = BIGLO(num);
-		num = 0;
-	    }
-	}
+    for (i = 0, num = 0; i < y->len; i++) { 
+	num += (long)BDIGITS(x)[i] - BDIGITS(y)[i];
+	zds[i] = BIGLO(num);
+	num = BIGDN(num);
+    } 
+    while (num && i < x->len) {
+	num += BDIGITS(x)[i];
+	zds[i++] = BIGLO(num);
+	num = BIGDN(num);
     }
-
+    while (i < x->len) {
+	zds[i++] = BDIGITS(x)[i];
+    }
+    
     return bignorm(z);
 }
 
@@ -541,10 +527,8 @@ bigadd(x, y, sign)
     char sign;
 {
     struct RBignum *z;
-    USHORT *zds;
     long num;
     UINT i, len;
-
     if (x->sign == (y->sign ^ sign)) {
 	if (y->sign == sign) return bigsub(y, x);
 	return bigsub(x, y);
@@ -557,27 +541,24 @@ bigadd(x, y, sign)
 	len = y->len + 1;
     }
     z = (struct RBignum*)bignew(len, sign==y->sign);
-    zds = BDIGITS(z);
-
-    i = len;
-    while (i--) zds[i] = 0;
-    i = y->len;
-    while (i--) zds[i] = BDIGITS(y)[i];
 
-    i = 0; num = 0;
-    do {
-	num += (long)zds[i] + BDIGITS(x)[i];
-	zds[i++] = BIGLO(num);
-	    num = BIGDN(num);
-    } while (i < x->len);
-    if (num) {
-	while (i < y->len) {
-	    num += zds[i];
-	    zds[i++] = BIGLO(num);
-	    num = BIGDN(num);
-	}
-	BDIGITS(z)[i] = num;
+    if (x->len > y->len) {
+        struct RBignum* t = x; x = y; y = t;
+    }
+    for (i = 0, num = 0; i < x->len; i++) {
+	num += (long)(BDIGITS(x)[i]) + BDIGITS(y)[i];
+	BDIGITS(z)[i] = BIGLO(num);
+	num = BIGDN(num);
+    }
+    while (num && i < y->len) {
+	num += BDIGITS(y)[i];
+	BDIGITS(z)[i++] = BIGLO(num);
+	num = BIGDN(num);
+    }
+    while (i < y->len) {
+	BDIGITS(z)[i++] = BDIGITS(y)[i];
     }
+    BDIGITS(z)[i] = num;
 
     return bignorm(z);
 }
@@ -649,20 +630,20 @@ big_mul(x, y)
     z = bignew(j, x->sign==y->sign);
     zds = BDIGITS(z);
     while (j--) zds[j] = 0;
-    do {
-	j = 0;
-	if (BDIGITS(x)[i]) {
-	    do {
-		n += zds[i + j] + ((unsigned long)BDIGITS(x)[i]*BDIGITS(y)[j]);
-		zds[i + j++] = BIGLO(n);
-		n = BIGDN(n);
-	    } while (j < y->len);
-	    if (n) {
-		zds[i + j] = n;
-		n = 0;
-	    }
+    for (i = 0; i < x->len; i++) {
+	unsigned long dd = BDIGITS(x)[i]; 
+	if (dd == 0) continue;
+	n = 0;
+	for (j = 0; j < y->len; j++) {
+	    int ee = n + dd * BDIGITS(y)[j];
+	    n = zds[i + j] + ee;
+	    if (ee) zds[i + j] = BIGLO(n);
+	    n = BIGDN(n);
 	}
-    } while (++i < x->len);
+	if (n) {
+	    zds[i + j] = n;
+	}
+    }
 
     return bignorm(z);
 }
@@ -681,7 +662,7 @@ bigdivmod(x, y, div, mod)
 
     yds = BDIGITS(y);
     if (ny == 0 && yds[0] == 0) num_zerodiv();
-    if (nx < ny) {
+    if (nx < ny	|| nx == ny && BDIGITS(x)[nx - 1] < BDIGITS(y)[ny - 1]) {
 	if (div) *div = INT2FIX(0);
 	if (mod) *mod = bignorm(x);
 	return;
@@ -692,7 +673,7 @@ bigdivmod(x, y, div, mod)
 	z = big_clone(x);
 	zds = BDIGITS(z);
 	t2 = 0; i = nx;
-	while(i--) {
+	while (i--) {
 	    t2 = BIGUP(t2) + zds[i];
 	    zds[i] = t2 / dd;
 	    t2 %= dd;
@@ -740,24 +721,21 @@ bigdivmod(x, y, div, mod)
 	if (q) {
 	    i = 0; num = 0; t2 = 0;
 	    do {			/* multiply and subtract */
+		int ee;
 		t2 += (unsigned long)yds[i] * q;
-		num += zds[j - ny + i] - BIGLO(t2);
-		if (num < 0) {
-		    zds[j - ny + i] = num + BIGRAD;
-		    num = -1;
-		}
-		else {
-		    zds[j - ny + i] = num;
-		    num = 0;
-		}
+		ee = num - BIGLO(t2);
+		num = zds[j - ny + i] + ee;
+		if (ee) zds[j - ny + i] = BIGLO(num);
+		num = BIGDN(num);
 		t2 = BIGDN(t2);
 	    } while (++i < ny);
 	    num += zds[j - ny + i] - t2; /* borrow from high digit; don't update
*/
 	    while (num) {		/* "add back" required */
 		i = 0; num = 0; q--;
 		do {
-		    num += (long) zds[j - ny + i] + yds[i];
-		    zds[j - ny + i] = BIGLO(num);
+		    int ee = num + yds[i];
+		    num = (long) zds[j - ny + i] + ee;
+		    if (ee) zds[j - ny + i] = BIGLO(num);
 		    num = BIGDN(num);
 		} while (++i < ny);
 		num--;

In This Thread

Prev Next