PARACT プログラム 2台のPCの計算結果が合わない。

 投稿者:たろさ  投稿日:2017年 4月26日(水)19時13分33秒
  今回は、何が原因なのか、わかりません。

しばっち様のエラトステネスの篩を手本にして、高速化に挑戦中のトラブルです。

1e9     50847534
2e9     98222287

1e7 step で素数をカウントするプログラム AMD では正常終了 精度確認も完了

計算時間は264.51s    サンダラムの篩よりも高速

AMD Athlon(tm) 64 Processor 3800+
  周波数 : 2.40 GHz
メモリー : 3.00 GB
Microsoft Windows 8.1(32 ビット)

-------------------------------------------



■ パソコン環境
 ウィンドウズ : Microsoft Windows 7
 サービスパック : なし
 システムの種類 : 32 ビット
        メモリー : 3.00 GB
   プロセッサー :Intel Core i7 4790K
Core Speed 4499.0 MHz
Multiplier x Bus Speed 45.0 x 100.0 MHz

---------------------------------------------
画面を見てビックリ 誤差も桁が違います。

計算速度も13.29s

数日かけて やっと 辿り着けたと思って ビックリ ガッカリしてます。


制作途中のプログラムです。お見苦しい点はお許しください。
-----------------------------------------------------------

! 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)
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)
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)
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
END SUB

-------------------------------------------------

しばっち様のエラトステネスの篩を素数リストで篩いました。思った以上に高速です。

しかし、AMDのシングルコアの計算結果は正常で、インテル 4コアが合いません。

---------------------------------------------------------------------------

困りました。

http://blogs.yahoo.co.jp/donald_stinger

 

Re: PARACT プログラム 2台のPCの計算結果が合わない。

 投稿者:たろさ  投稿日:2017年 4月27日(木)05時56分37秒
  たろささんへのお返事です。

> 今回は、何が原因なのか、わかりません。
>
打ちのめされたココロを 再起動

プログラムを再点検

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

 

戻る