Paract BASIC

 投稿者:白石和夫  投稿日:2017年 4月18日(火)08時45分28秒
  JIS Full BASIC 実時間機能単位で定義された並行活動(Parallel Activity)の実装です。
平たく言えば,マルチスレッドプログラミングが可能なBASICです。
並行活動を持たないプログラムも実行可能です。
文字出力のみのプログラムはそのままでもBASICAccで実行するより少し速くなります。
グラフィックスは,そのままだとBASICAccより少し遅くなります。並行活動に処理を分割しないと速くなりません。
Lazarus+FPCでコンパイルすればMAC,Linuxでも動作しますが,不完全です。

https://ja.osdn.net/projects/decimalbasic/releases/p15417

 

Re: Paract BASIC

 投稿者:たろさ  投稿日:2017年 4月18日(火)13時37分46秒
  > No.4311[元記事へ]

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

> JIS Full BASIC 実時間機能単位で定義された並行活動(Parallel Activity)の実装です。
> 平たく言えば,マルチスレッドプログラミングが可能なBASICです。
> 並行活動を持たないプログラムも実行可能です。
> 文字出力のみのプログラムはそのままでもBASICAccで実行するより少し速くなります。
> グラフィックスは,そのままだとBASICAccより少し遅くなります。並行活動に処理を分割しないと速くなりません。
> Lazarus+FPCでコンパイルすればMAC,Linuxでも動作しますが,不完全です。
>
>
早速テストしました。シングルコアです。

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

計算時間の比較です。
Lazarus 1.6.4 (FPC 3.0.2)

Paract BASIC 0.8.0   ---75.48秒(1分15.48秒)

BASIC Acc Ver. 1.0.3.0 ---76.20秒(1分16.20秒)

BASIC Acc Ver. 1.0.2.0 ---94.46秒(1分34.46秒)

■ パソコン環境
ウィンドウズ : Microsoft Windows 7
 サービスパック : なし
 システムの種類 : 32 ビット
        メモリー : 3.00 GB
   プロセッサー :Intel Core i7 4790K(4.5GHz)

Lazarus 1.6.2 (FPC 3.0.0)

Paract BASIC 0.8.0   11.14秒

BASIC Acc Ver. 1.0.3.0    17.68秒

下記のプログラムではCPUの稼働率が30%程度でした。AMDとi7 4790Kの比較で5倍以上になったのは、初めてです。

テストプログラム
1E+15-1E+10 TO 1E+15  1億単位素数リスト出力プログラム

!6n±1篩 prime number Ver.2.3
DECLARE EXTERNAL FUNCTION cprime
DECLARE EXTERNAL SUB sqprime
DECLARE EXTERNAL SUB TIMES
OPTION ARITHMETIC NATIVE
!PRINT DATE$;"/"; TIME$
LET t0=TIME

LET k=31622803
LET k2=1951960
!エラトステネスの篩
LET Fu=5633
DIM P(Fu)
DIM A(739)  !素数
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

DIM GT(k2)
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 739
   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 GT(1)=2
LET GT(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 GT(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 GT(cz)=6*n+1
       END IF
    NEXT n
    !1E+15-1E+10 TO 1E+15
    ! 9999901 TO 10000000 (1億単位)
    LET SA=10000000 !MIN 2 (1億to)
    LET SB=10000000 !MAX 1E15-1
    CALL sqprime(SA,SB,k2,GT)
    DIM Bb(SA TO SB)
    OPEN #2:NAME "prime_pi1.txt",ACCESS INPUT

    FOR i=SA TO SB
       INPUT #2: BB(i)
    NEXT i
    CLOSE #2

    DIM Pn(101)   !1億単位
    MAT READ Pn
    DATA 29844280881108,29844283778350,29844286673183,29844289567927,29844292461897,29844295359129,29844298254684,29844301151063,29844304047136,29844306941518
    DATA 29844309839746,29844312733943,29844315627199,29844318521334,29844321418009,29844324314523,29844327210344,29844330105150,29844332999978,29844335895709
    DATA 29844338789244,29844341684694,29844344580567,29844347478427,29844350373782,29844353269227,29844356162629,29844359058710,29844361952280,29844364848357
    DATA 29844367743371,29844370638200,29844373534893,29844376430806,29844379325503,29844382222516,29844385117770,29844388013180,29844390908262,29844393802839
    DATA 29844396697666,29844399592539,29844402489028,29844405385715,29844408281893,29844411175272,29844414071355,29844416966188,29844419861029,29844422754610
    DATA 29844425650435,29844428546187,29844431441463,29844434337930,29844437232986,29844440128474,29844443023109,29844445918084,29844448814585,29844451709782
    DATA 29844454605616,29844457501216,29844460396817,29844463292125,29844466187497,29844469083188,29844471978285,29844474874218,29844477769269,29844480665850
    DATA 29844483562161,29844486457507,29844489352992,29844492248320,29844495141763,29844498038403,29844500932757,29844503827750,29844506722855,29844509616736
    DATA 29844512511515,29844515407744,29844518304021,29844521200361,29844524094726,29844526989128,29844529883655,29844532780287,29844535677285,29844538574330
    DATA 29844541468540,29844544364058,29844547260257,29844550153650,29844553050083,29844555944162,29844558841306,29844561736036,29844564632690,29844567526938
    DATA 29844570422669

    ! 9999901:  1:29844280881108
    ! 9999902:  2:29844283778350
    !
    !10000000:100:29844567526938
    LET k6=SA*1E8-1E8
    FOR n=SA TO SB
       LET c1=Pn(n-9999900)
       LET k2=Bb(n) !π(x)
       LET k6=k6+1E8
       LET C=cprime(c1,k2,k6,GT)
       LET c1=c1+c
       PRINT n;":";c1;":";c
    NEXT n

    LET TM=TIME-t0
    PRINT USING"######.##":TM;
    PRINT "秒"
    !PRINT DATE$;"/"; TIME$
    CALL TIMES(ROUND(TM,2))
END

EXTERNAL FUNCTION cprime (c2,k2,k6,GT())
    OPTION ARITHMETIC NATIVE
    LET k4=k6-1E8
    LET B6=IP(k6/30)
    LET U=IP(k6/6)
    LET W=IP(k4/6)
    LET M7=W

    DIM x(W-M7 TO U-M7)
    DIM y(W-M7 TO U-M7)
    MAT x = ZER !(6*n-1)
    MAT y = ZER !(6*n+1)

    FOR n=3 TO k2
       LET P6=GT(n)
       LET G1=IP(W/P6)
       IF MOD(P6+1,6)=0 THEN !(6*n-1)
          LET r6=(P6+1)/6
          FOR i=G1 TO B6
             IF P6*i+r6<W THEN GOTO 140
             IF P6*i+r6>U THEN EXIT FOR
             LET x(P6*i+r6-M7)=1
140       NEXT i
       END IF

       IF MOD(P6-1,6)=0 THEN
          LET r6=(P6-1)/6
          FOR i=G1 TO B6
             IF P6*i-r6<W THEN GOTO 150
             IF P6*i-r6>U THEN EXIT FOR
             LET x(P6*i-r6-M7)=1
150       NEXT i
       END IF

       IF MOD(P6+1,6)=0 THEN !(6*n+1)
          LET r6=(P6+1)/6
          FOR i=G1 TO B6
             IF P6*i-r6<W THEN GOTO 160
             IF P6*i-r6>U THEN EXIT FOR
             LET y(P6*i-r6-M7)=1
160       NEXT i
       END IF

       IF MOD(P6-1,6)=0 THEN
          LET r6=(P6-1)/6
          FOR i=G1 TO B6
             IF P6*i+r6<W THEN GOTO 170
             IF P6*i+r6>U THEN EXIT FOR
             LET y(P6*i+r6-M7)=1
170       NEXT i
       END IF
    NEXT n

    LET Cc=0
    FOR n=W-M7 TO U-M7
       LET ST=n+M7
       IF x(n)=0 THEN
          IF 6*ST-1>k4 AND 6*ST-1<k6 THEN
             LET cc=cc+1
             LET c2=c2+1
             PRINT 6*ST-1;":";c2
          END IF
       END IF
       IF y(n)=0 THEN
          IF 6*ST+1>k4 AND 6*ST+1<k6 THEN
             LET cc=cc+1
             LET c2=c2+1
             PRINT 6*ST+1;":";c2
          END IF
       END IF
    NEXT n
    LET cprime=cc
    PRINT
END FUNCTION

EXTERNAL  SUB sqprime(SA,SB,k2,GT())
    OPTION ARITHMETIC NATIVE
    OPEN #2:NAME "prime_pi1.txt",RECTYPE INTERNAL
    ERASE #2
    LET x=1E8
    FOR i=1 TO k2-1
       LET v=GT(i)^2
       LET vi=GT(i+1)^2
       LET vv=vi-v
       IF x =< v THEN
          CALL sqrp(1)
          IF vv>=1E8 THEN
             LET vt=IP(vv/1E8)
             CALL sqrp(vt)
          END IF
       END IF
    NEXT i

    SUB sqrp(vo)
       FOR ns=1 TO vo
          LET C=C+1
          LET X=X+1E8
          IF C>=SA AND SB>=C THEN
             WRITE #2:i
          END IF
       NEXT ns
    END SUB
    CLOSE #2
END SUB

EXTERNAL SUB TIMES(N)  !時間変換(秒)to(時:分)
    LET M=IP(N/60)
    LET I=MOD(N,60)
    LET N=M
    LET M=IP(N/60)
    LET S=MOD(N,60)
    PRINT STR$(M)&"時間";STR$(S)&"分";
    PRINT USING"##.##":I;
    PRINT "秒"
END SUB

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

 

戻る