The Q6600
Benchmarks Game

mandelbrot Free Pascal #6 program

source code

(* The Computer Language Benchmarks Game
   https://salsa.debian.org/benchmarksgame-team/benchmarksgame/

   - contributed by Ales Katona
   - modified by Vincent Snijders
   - optimized and multithreaded by Jean de La Taille
   - modified by Jeppe Johansen
   - modified by Peter Blackman (Restore 'CalculatePoint' as leaf function, better use of registers)
   - refactored and modified to use PasMP by Akira1364
*)

program Mandelbrot;

uses CMem, {$IFDEF UNIX}CThreads,{$ENDIF} SysUtils, Math, PasMP;

const N: Int32 = 200;

var
  DimX: Int32;
  NInv: Double;
  TextBuf: PByte;

  procedure DoMandelbrot(const Job: PPasMPJob;
                         const ThreadIndex: Int32;
                         const Data: Pointer;
                         const FromIndex, ToIndex: SizeInt);
  var
    BufIndex, Bit, Bits, X: Int32;
    Index: SizeInt;
    CR, CI: Double;

    function CalculatePoint(const CX, CY: Double): Boolean; inline;
    var
      I: Int32;
      Limit: Double = 4;
      Two: Double = 2;
      ZR, ZI, TI, TR: Double;
    begin
      ZR := 0; ZI := ZR; TR := ZR; TI := ZR;
      for I := 1 to 50 do begin
        ZI := Two * ZR * ZI + CY;
        ZR := TR - TI + CX;
        TI := ZI * ZI;
        TR := ZR * ZR;
        if (TR + TI >= Limit) then Exit(True);
      end;
      CalculatePoint := False;
    end;

  begin
    for Index := FromIndex to ToIndex do begin
      BufIndex := Index * DimX;
      Prefetch(TextBuf[BufIndex]);
      Bit := 128;
      Bits := 0;
      CI := ((Index + Index) * NInv) - 1.0;
      for X := 0 to Pred(N) do begin
        CR := ((X + X) * NInv) - 1.5;
        if CalculatePoint(CR, CI) then Bits := Bits or Bit;
        Bit := Bit shr 1;
        if Bit = 0 then begin
          TextBuf[BufIndex] := not Bits;
          Inc(BufIndex);
          Bits := 0;
          Bit := 128;
        end;
      end;
    end;
  end;

var
  Len: SizeUInt;
  IO: PText;

begin
  if ParamCount > 0 then Val(ParamStr(1), N);
  DimX := Ceil(N / 8);
  NInv := 1 / N;
  Len := DimX * N;
  GetMem(TextBuf, Len);
  with TPasMP.CreateGlobalInstance() do
    Invoke(ParallelFor(nil, 0, Pred(N), @DoMandelbrot));
  IO := @Output;
  Write(IO^, 'P4', #10, N, ' ', N, #10);
  Flush(IO^);
  FileWrite(StdOutputHandle, TextBuf[0], Len);
  FreeMem(TextBuf);
end.
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
Free Pascal Compiler version 3.2.0 [2020/06/14] for x86_64


Sat, 20 Jun 2020 17:41:13 GMT

MAKE:
mv mandelbrot.fpascal-6.fpascal mandelbrot.fpascal-6.pas
/opt/src/fpc-3.2.0/bin/fpc -FuInclude/fpascal -XXs -O3 -Ci- -Cr- -g- -CpCOREI -Tlinux  -oFPASCAL_RUN mandelbrot.fpascal-6.pas
Free Pascal Compiler version 3.2.0 [2020/06/14] for x86_64
Copyright (c) 1993-2020 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling mandelbrot.fpascal-6.pas
mandelbrot.fpascal-6.pas(82,5) Note: Call to subroutine "function TPasMP.GetJobWorkerThread:TPasMPJobWorkerThread;" marked as inline is not inlined
mandelbrot.fpascal-6.pas(82,5) Note: Call to subroutine "procedure TPasMP.PushJob(const Job:PPasMPJob;const JobWorkerThread:TPasMPJobWorkerThread);" marked as inline is not inlined
Linking FPASCAL_RUN
88 lines compiled, 3.1 sec
2 note(s) issued
mv FPASCAL_RUN mandelbrot.fpascal-6.fpascal_run
rm mandelbrot.fpascal-6.pas

3.60s to complete and log all make actions

COMMAND LINE:
./mandelbrot.fpascal-6.fpascal_run 16000

(BINARY) PROGRAM OUTPUT NOT SHOWN