[Shootout-list] New benchmark?

Greg Buchholz sleepingsquirrel@member.fsf.org
Fri, 17 Dec 2004 09:45:50 -0800 (PST)


--0-231543983-1103305550=:79450
Content-Type: text/plain; charset=us-ascii
Content-Id: 
Content-Disposition: inline

    Since there seems to be a dearth of "same thing" benchmarks,
I'd thought I'd throw something out there to see if anyone is
interested in another one.  It mostly tests floating point math
and tight loops. Below is the description and a C, Perl, and
Haskell implementation.


--Mandelbrot Benchmark--

Each program should do the same thing.

In this benchmark, we're plotting the Mandelbrot set
(http://mathworld.wolfram.com/MandelbrotSet.html).  For each point
in the complex plane, a point C is a member of the Mandelbrot set
if the sequence...

    Z(n+1) = Z(n)^2 + C

...does not diverge towards infinity.  We'll approximate the
process by limiting the iterations to 50 and checking if the final
value is less than 2.  The program takes a parameter N, and
produces, on standard output, an N by N bitmap in the PPM
(portable pixmap w/ magic number P3) file format.
(http://www-info2.informatik.uni-wuerzburg.de/mitarbeiter/wolfram/lehre/bildformate.html#ppm)
The bounding box of the square area we are plotting is
[-1.5-i,0.5+i], which is divided into N by N pixels.  Since this
is a "same thing" test, feel free to implement any optimizations
(manual/programmatic loop unrolling, symmetry, etc.)

Greg Buchholz




		
__________________________________ 
Do you Yahoo!? 
Dress up your holiday email, Hollywood style. Learn more. 
http://celebrity.mail.yahoo.com
--0-231543983-1103305550=:79450
Content-Type: text/x-haskell; name="fractal.hs"
Content-Description: fractal.hs
Content-Disposition: inline; filename="fractal.hs"

-- Fractal.hs mandlebrot example
-- dumps a *.ppm graphics file to stdout
-- compile:  ghc -O2 -o fractal fractal.hs
-- run: fractal 600 >mandel.ppm
-- by Greg Buchholz

import Complex
import System(getArgs)

main = do   [arg] <- getArgs
            let width = read arg
            let pts = points width width        
            putStr $ "P3\n" ++ arg ++ " " ++ arg ++ "\n255\n"
            putPPM (fractal pts)    

limit  = 2
iter   = 50+1 -- add one to compensate for the 'iterate' function

points w h = [(2*x/w - 1.5) :+ (2*y/h - 1) | y<-[0..h-1], x<-[0..w-1]]

mandel c z = z * z + c

fractal pts = map (\f-> length (takeIter (iterate f (0:+0)))) (map mandel pts)
        where takeIter a = take iter (takeWhile (\x-> magnitude(x)<limit) a)
       
putPPM [] = putStr ""
putPPM (x:xs)  | x == iter = do { putStr "0   0   0 \n";  putPPM xs}
               | otherwise = do { putStr "255 255 255\n"; putPPM xs}

--0-231543983-1103305550=:79450
Content-Type: text/x-c; name="fractal.c"
Content-Description: fractal.c
Content-Disposition: inline; filename="fractal.c"

//Mandelbrot benchmark
//compile:  gcc -O2 -o fractal fractal.c
//run:  fractal 600 >mandel.ppm
//by Greg Buchholz

#include<stdio.h>

int main (int argc, char **argv)
{
    int w, h, x, y;
    int i, iter = 50;
    double limit = 2.0;
    double Zr, Zi, Cr, Ci, Tr, Ti;
    
    w = atoi(argv[1]);
    h = w;

    printf("P3\n%d %d\n255\n",w,h);

    for(y=0;y<h;y++) 
    {
        for(x=0;x<w;x++)
        {
            Zr = 0.0; Zi = 0.0;
            Cr = (2*(double)x/w - 1.5); Ci=(2*(double)y/h - 1);
        
            for (i=0;i<iter;i++)
            {
                Tr = Zr*Zr - Zi*Zi + Cr;
                Ti = 2*Zr*Zi + Ci;
                Zr = Tr; Zi = Ti;
                if (Zr*Zr+Zi*Zi > limit*limit)
                    break;
            }
        
            if(Zr*Zr+Zi*Zi > limit*limit) 
                printf("255 255 255\n");
            else
                printf("0   0   0 \n");
        }
    }	

    return(0);
}

--0-231543983-1103305550=:79450
Content-Type: text/x-perl; name="fractal.pl"
Content-Description: fractal.pl
Content-Disposition: inline; filename="fractal.pl"

#!/usr/bin/perl -w
#
#Mandelbrot benchmark program
#run:  fractal.pl 600 > mandel.ppm
#by Greg Buchholz

my $w=shift;
my $h=$w;
my $limit = 2; my $limit_sqr = $limit * $limit;
my $iter = 50;

print "P3\n$w $h\n255\n";

my $x,  my $y;
my $Zr, my $Zi, my $Cr, my $Ci, my $Tr, my $Ti;

for($y=0;$y<$h;$y++) 
{
    for($x=0;$x<$w;$x++)
    {
        $Zr= 0; $Zi=0;
        $Cr = (2*$x/$w - 1.5); $Ci=(2*$y/$h - 1);
        
        for (1..$iter)
        {
            $Tr = $Zr*$Zr - $Zi*$Zi + $Cr;
            $Ti = 2*$Zr*$Zi + $Ci;
            $Zr = $Tr; $Zi = $Ti;
            last if ($Zr*$Zr+$Zi*$Zi>$limit_sqr);
        }
        
        if($Zr*$Zr+$Zi*$Zi>$limit_sqr) 
        {
            print "255 255 255\n";
        }else
        {
            print "0   0   0 \n";
        }
    }
}	


--0-231543983-1103305550=:79450--