Re: Sieve of Sundaram サンダラムの篩(ふるい)

 投稿者:白石 和夫  投稿日:2017年 4月25日(火)13時52分41秒
  私のところでもExtype12001が出ます。
signal文で終了のシグナルを発行したのを確認しても,その時点ではまだその並行活動は終了していないかも知れません。
Full BASICには他の並行活動の状態を調べる手段が用意されていないので,終了したかどうかはSTART文を実行してみるまでわかりません。
EXTYPE12001の例外状態になるときは終了を待てばよいので,各start文を次のように変えれば動くと思います。

例 START PART2のとき
   DO
      WHEN EXCEPTION IN
         START PART2
         LET success=1
      USE
         IF EXTYPE=12001 THEN
            LET success=0
            WAIT DELAY 0.01
         ELSE
            exit handler
         END IF
      END WHEN
   LOOP UNTIL success=1

簡略化して
  DO
      WHEN EXCEPTION IN
         START PART3
         LET success=1
      USE
         LET success=0
         WAIT DELAY 0.01
      END WHEN
  LOOP UNTIL success=1
でも大丈夫です(多分)。

USE行の下に
  PRINT EXTYPE
を追加して実行してみると,ときたま
12001
を表示するのが観察できます。


              
 

Re: Sieve of Sundaram サンダラムの篩(ふるい)

 投稿者:たろさ  投稿日:2017年 4月25日(火)18時32分35秒
  > No.4319[元記事へ]

白石 和夫さんへのお返事です。

> 私のところでもExtype12001が出ます。
> signal文で終了のシグナルを発行したのを確認しても,その時点ではまだその並行活動は終了していないかも知れません。
> Full BASICには他の並行活動の状態を調べる手段が用意されていないので,終了したかどうかはSTART文を実行してみるまでわかりません。
> EXTYPE12001の例外状態になるときは終了を待てばよいので,各start文を次のように変えれば動くと思います。
>
> 例 START PART2のとき
>    DO
>       WHEN EXCEPTION IN
>          START PART2
>          LET success=1
>       USE
>          IF EXTYPE=12001 THEN
>             LET success=0
>             WAIT DELAY 0.01
>          ELSE
>             exit handler
>          END IF
>       END WHEN
>    LOOP UNTIL success=1
>
> 簡略化して
>   DO
>       WHEN EXCEPTION IN
>          START PART3
>          LET success=1
>       USE
>          LET success=0
>          WAIT DELAY 0.01
>       END WHEN
>   LOOP UNTIL success=1
> でも大丈夫です(多分)。
>
> USE行の下に
>   PRINT EXTYPE
> を追加して実行してみると,ときたま
>  12001
> を表示するのが観察できます。
>

有難うございました。家のPCでは安定して計算してます。

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

!Sieve of Sundaram Prime number Counting !Ver.2.1
!素数計数関数(英: Prime-counting function)π(x)
!Paract BASICによるマルチスレッド化プログラム
DECLARE STRUCTURE STRUCT1: 2 OF NUMERIC
DECLARE STRUCTURE STRUCT4: 1 OF NUMERIC
DECLARE SHARED buff1 OF STRUCT1
DECLARE SHARED buff2 OF STRUCT1
DECLARE SHARED buff3 OF STRUCT1
DECLARE SHARED buff4 OF STRUCT4
DECLARE SHARED buff5 OF STRUCT4
DECLARE SHARED buff6 OF STRUCT4

PARACT PART1
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC ST,I
LET t0=TIME
LET S=90000000001
LET E=100000000000 !pi(x)4118054813
LET ST=10000000
LET TOTAL=3722428991!9e10,3325059246,8e10,2925699539,7e10,2524038155,6e10,2119654578,5e10,1711955433,4e10,1711955433,3e10,1300005926,2e10,882206716,1e10,455052511,1e9,50847534
DECLARE EXTERNAL FUNCTION ERATOS
FOR I=S TO E STEP ST
   PUT TO BUFF1 FROM I,ST
   SIGNAL Ready1
   DO
      WHEN EXCEPTION IN
         START PART2
         LET success=1
      USE
         LET success=0
         WAIT DELAY 0.01
      END WHEN
   LOOP UNTIL success=1
   PUT TO BUFF2 FROM I,ST
   SIGNAL Ready3
   START PART3
   PUT TO BUFF3 FROM I,ST
   SIGNAL Ready5
   START PART4
   LET L1=ERATOS(I,I+ST/4-1)
   WAIT EVENT Ready2
   GET FROM BUFF4 TO L2
   WAIT EVENT Ready4
   GET FROM BUFF5 TO L3
   WAIT EVENT Ready6
   GET FROM BUFF6 TO L4
   LET TOTAL=TOTAL+L1+L2+L3+L4
   PRINT I;"~";I+ST-1;":";L1+L2+L3+L4;TOTAL
NEXT I
LET TM=TIME-t0
PRINT USING"####." & REPEAT$("#",2):TM;
PRINT "秒"
END PARACT

PARACT PART2
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC I,ST
DECLARE NUMERIC L2
DECLARE EXTERNAL FUNCTION ERATOS
WAIT EVENT Ready1
GET FROM BUFF1 TO I,ST
LET L2=ERATOS(I+ST/4,I+ST/2-1)
PUT TO BUFF4 FROM L2
SIGNAL Ready2
END PARACT

PARACT PART3
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC I,ST
DECLARE NUMERIC L3
DECLARE EXTERNAL FUNCTION ERATOS
WAIT EVENT Ready3
GET FROM BUFF2 TO I,ST
LET L3=ERATOS(I+ST/2,I+3*ST/4-1)
PUT TO BUFF5 FROM L3
SIGNAL Ready4
END PARACT

PARACT PART4
OPTION ARITHMETIC NATIVE
DECLARE NUMERIC I,ST
DECLARE NUMERIC L4
DECLARE EXTERNAL FUNCTION ERATOS
WAIT EVENT Ready5
GET FROM BUFF3 TO I,ST
LET L4=ERATOS(I+3*ST/4,I+ST-1)
PUT TO BUFF6 FROM L4
SIGNAL Ready6
END PARACT

EXTERNAL  FUNCTION ERATOS(N,M)
OPTION ARITHMETIC NATIVE
LET N=N-1
LET COUNT=0
LET k8=INT(N/2)
LET M7=k8-1
LET k9=INT(M/2)
DIM A(k9-M7)
MAT A=ZER
LET  S=3
LET  D=4
LET k=INT(SQR(k9))*3
DO
   LET B=D+S*INT((k8-D)/S)
   DO UNTIL B>=k8
      LET B=B+S
   LOOP
   FOR I=B TO k9 STEP S
      LET A(I-M7)=1
   NEXT I
   LET  S=S+2
   LET  D=D+3
LOOP UNTIL D>k
FOR n=1 TO k9-M7
   IF (n+M7)*2+1>M THEN EXIT FOR
   IF A(n)=0 THEN LET COUNT=COUNT+1
   !LET Sun=(n+M7)*2+1
   !PRINT Sun
NEXT n
LET ERATOS=COUNT
END FUNCTION
--------------------------------------------

1000000001      50847534
100000000000  4118054813

上記の範囲を計算すると、素数の個数が足りません。

素数の個数 精度確認の範囲
1e10     455052511
2e10     882206716
3e10    1300005926
4e10    1711955433
5e10    2119654578
6e10    2524038155
7e10    2925699539
8e10    3325059246
9e10    3722428991
--------------------------------------

1e10     455052511
2e10     882206716


1e10 間の範囲では誤差は見られませんでした。計算範囲の4分割とサンダラムの篩の1/2の数値合わせを見直しています。


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

 

戻る