|
たろささんへのお返事です。
> 今回は、何が原因なのか、わかりません。
>
打ちのめされたココロを 再起動
プログラムを再点検
PC AMD Athlon(2.40 GHz)でプログラムを書いたので
PC i7-4790K(4.5GHz) で 修正しました。
ヘルプを参照して
単純に並列アクティビティ プログラムは、
PARACT Par1
PRINT "ABC"
START Par2
END PARACT
PARACT Par2
PRINT "XYZ"
END PARACT
EXTERNAL FUNCTIONやEXTERNAL SUBなどの外部
十進BASIC プログラムのメインと外部の様に使えるはずですね。
単一コア と複数のコアの違いが出ました。
SHAREDポート経由のデータ転送 PUT TO and GET FROM (に辿り着く)
概略
PARACT Par1
DECLARE EXTERNAL SUB prime
CALL prime(k,k3)
WAIT EVENT Ok5
DECLARE EXTERNAL SUB sqprime
CALL sqprime(101,200,k3)
DECLARE NUMERIC B(101 TO 200)
WAIT EVENT Ok6
GET FROM shb TO B
END PARACT
ヘルプを参照して
共有ポート経由でのデータ転送は、PUT TO文とGET FROM文で実行されます。
PARACT Par1
GET FROM shb TO B 配列B(101 TO 200)を読み込確認後は
PARACT Par2 以下は
共有 配列B(101 TO 200)から読み込出来ると思いましたが
START Par2 が先の場合は
共有 配列B(101 TO 200) 空のDATAを読み込む事になるようでした。
対処方として、START Par2 を Synchronization(同期)
待たせたので、計算時間が遅くなった?
i7-4790K(4.5GHz) 17.49s
AMD Athlon(2.40 GHz) 263.21s 変わらず。
! Sieve of Eratosthenes
DECLARE STRUCTURE struct1: 1 OF NUMERIC
DECLARE STRUCTURE struct2: 1 OF NUMERIC(9593)
DECLARE STRUCTURE struct3: 1 OF NUMERIC(101 TO 200)
DECLARE SHARED sha OF struct2
DECLARE SHARED shb OF struct3
DECLARE MESSAGE mes2 OF struct1
DECLARE MESSAGE mes3 OF struct1
DECLARE MESSAGE mes4 OF struct1
PARACT PART1
OPTION ARITHMETIC NATIVE
START Part2
START PART3
START PART4
LET k=100003
LET k3=9593
DECLARE EXTERNAL SUB prime
CALL prime(k,k3)
WAIT EVENT Ok5
LET S=1E9+1
LET E=2E9
LET ST=1E7
DECLARE EXTERNAL SUB sqprime
CALL sqprime(101,200,k3)
DECLARE NUMERIC B(101 TO 200)
WAIT EVENT Ok6
GET FROM shb TO B
LET TOTAL=50847534
DECLARE EXTERNAL FUNCTION ERATOS
DECLARE NUMERIC X,Y,Z
LET cc=101
FOR I=S TO E STEP ST
LET k2=B(cc)
LET cc=cc+1
LET L=ERATOS(I,I+ST/4-1,k2)
RECEIVE FROM mes2 TO X
WAIT EVENT Ready2
RECEIVE FROM mes3 TO Y
WAIT EVENT Ready3
RECEIVE FROM mes4 TO Z
WAIT EVENT Ready4
SIGNAL Ok2
SIGNAL Ok3
SIGNAL Ok4
LET L=L+X+Y+Z
LET TOTAL=TOTAL+L
PRINT I-1;I+ST-1;TOTAL;L
!PRINT TOTAL
NEXT I
END PARACT
PARACT PART2
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC B(101 TO 200)
WAIT EVENT Ok7
GET FROM shb TO B
LET S=1E9+1
LET E=2E9
LET ST=1E7
DECLARE EXTERNAL FUNCTION ERATOS
DECLARE NUMERIC L
LET cc=101
FOR I=S TO E STEP ST
LET k2=B(cc)
LET cc=cc+1
LET L=ERATOS(I+ST/4,I+ST/2-1,k2)
SEND TO mes2 FROM L
SIGNAL Ready2
WAIT EVENT Ok2
NEXT I
END PARACT
PARACT PART3
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC B(101 TO 200)
WAIT EVENT Ok8
GET FROM shb TO B
LET S=1E9+1
LET E=2E9
LET ST=1E7
DECLARE EXTERNAL FUNCTION ERATOS
DECLARE NUMERIC L
LET cc=101
FOR I=S TO E STEP ST
LET k2=B(cc)
LET cc=cc+1
LET L=ERATOS(I+ST/2,I+3*ST/4-1,k2)
SEND TO mes3 FROM L
SIGNAL ready3
WAIT EVENT Ok3
NEXT I
END PARACT
PARACT PART4
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC B(101 TO 200)
WAIT EVENT Ok9
GET FROM shb TO B
LET S=1E9+1
LET E=2E9
LET ST=1E7
DECLARE EXTERNAL FUNCTION ERATOS
DECLARE NUMERIC L
LET cc=101
FOR I=S TO E STEP ST
LET k2=B(cc)
LET cc=cc+1
LET L=ERATOS(I+3*ST/4,I+ST-1,k2)
SEND TO mes4 FROM L
SIGNAL ready4
WAIT EVENT Ok4
NEXT I
END PARACT
EXTERNAL FUNCTION ERATOS(N,M,k2)
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC G(9593) !素数
GET FROM sha TO G
DIM X(0 TO M-N+1)
LET COUNT=0
FOR I=2 TO k2 STEP 1
LET P=G(I)
IF MOD(N,P)=0 THEN
LET NN=N
ELSE
LET NN=INT(N/P+1)*P
END IF
IF N<=I THEN LET NN=NN+P
FOR J=NN TO M STEP P
LET X(J-N)=1
!PRINT i;p;j;n;j-n
NEXT J
NEXT I
FOR J=N TO M STEP 2
IF X(J-N)=0 THEN
LET COUNT=COUNT+1
END IF
NEXT J
LET ERATOS=COUNT
SIGNAL Ok7
END FUNCTION
EXTERNAL SUB prime(k,k2)
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC G(9593) !素数
!エラトステネスの篩
LET Fu=10007
LET Fm=1230
DIM P(Fu)
DIM A(Fm) !素数
MAT P=ZER
MAT A=ZER
LET A(1)=2
LET H1=1
FOR I=3 TO SQR(Fu) STEP 2
IF P(I)=0 THEN
FOR J=I*I TO Fu STEP I
LET P(J)=1
NEXT J
END IF
NEXT I
FOR I=3 TO Fu STEP 2
IF P(I)=0 THEN
LET H1=H1+1
LET A(H1)=I
END IF
NEXT I
LET Q=6
LET k7=k !篩の計算範囲
LET k5=IP(k7/Q)+1
DIM Au(k5),Av(k5)
MAT Au = ZER !(6*n-1)
MAT Av = ZER !(6*n+1)
FOR n=3 TO Fm
LET Pu=A(n)
IF MOD(Pu+1,Q)=0 THEN !(6*n-1)
LET ru=(Pu+1)/Q
FOR i=1 TO k5
IF Pu*i+ru>k5 THEN EXIT FOR
LET Au(Pu*i+ru)=1
NEXT i
END IF
IF MOD(Pu-1,Q)=0 THEN
LET ru=(Pu-1)/Q
FOR i=1 TO k5
IF Pu*i-ru>k5 THEN EXIT FOR
LET Au(Pu*i-ru)=1
NEXT i
END IF
IF MOD(Pu+1,Q)=0 THEN !(6*n+1)
LET ru=(Pu+1)/Q
FOR i=1 TO k5
IF Pu*i-ru>k5 THEN EXIT FOR
LET Av(Pu*i-ru)=1
NEXT i
END IF
IF MOD(Pu-1,Q)=0 THEN
LET ru=(Pu-1)/Q
FOR i=1 TO k5
IF Pu*i+ru>k5 THEN EXIT FOR
LET Av(Pu*i+ru)=1
NEXT i
END IF
NEXT n
LET G(1)=2
LET G(2)=3
LET cz=2
FOR n=1 TO k5
IF 6*n-1>k7 THEN GOTO 100
IF Au(n)=0 THEN
LET cz=cz+1
LET G(cz)=6*n-1
END IF
100 IF 6*n+1>k7 THEN EXIT FOR
IF Av(n)=0 THEN
LET cz=cz+1
LET G(cz)=6*n+1
END IF
NEXT n
PUT TO sha FROM G
SIGNAL Ok5
END SUB
EXTERNAL SUB sqprime(SA,SB,k2)
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC G(9593) !素数
GET FROM sha TO G
DECLARE NUMERIC B(101 TO 200)
LET x=1E7
LET x1=x
FOR i=1 TO k2-1
LET v=G(i)^2
LET vi=G(i+1)^2
LET vv=vi-v
IF x =< v THEN
CALL sqrp(1)
IF vv>=x1 THEN
LET vt=INT(vv/x1)
CALL sqrp(vt)
END IF
END IF
NEXT i
SUB sqrp(vo)
FOR ns=1 TO vo
LET C=C+1
LET X=X+x1
IF C>=SA AND SB>=C THEN
LET B(c)=i
END IF
NEXT ns
END SUB
PUT TO shb FROM B
SIGNAL Ok6
SIGNAL Ok7
SIGNAL Ok8
SIGNAL Ok9
END SUB
--------------------------------------
サンダラムの篩の最速で 18.95s
なお、エラトステネスの篩を素数リストだけで篩えるのか?
数値実験プログラムです。素数をカウントする 精度については未確認です。
http://blogs.yahoo.co.jp/donald_stinger
|
|