/mobile Handheld Friendly website

 performance measurements

Each table row shows performance measurements for this C++ g++ program with a particular command-line input value N.

 N  CPU secs Elapsed secs Memory KB Code B ≈ CPU Load
1,0000.120.03?1035  100% 100% 100% 100%
4,0001.770.452,4521035  100% 100% 100% 98%
16,00027.967.0231,7601035  99% 100% 100% 99%

Read the ↓ make, command line, and program output logs to see how this program was run.

Read mandelbrot benchmark to see what this program should do.

 notes

gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu8)

 mandelbrot C++ g++ #6 program source code

/*   
   The Computer Language Benchmarks Game
   http://benchmarksgame.alioth.debian.org/

   contributed by Paolo Bonzini
   further optimized by Jason Garrett-Glaser
   OpenMP by The Anh Tran
   10-11-2010, modified by The Anh Tran:
      _ remove builtin function
      _ copy bit shift idea from C entry
*/

#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <sched.h>
#include <memory.h>

#include <omp.h>
#include <sys/types.h>

#define L2_CACHE_LINE   64
#define ALIGN         __attribute__ ((aligned(L2_CACHE_LINE)))


typedef unsigned char   byte;
typedef double         v2d   __attribute__ ((vector_size(16)));
typedef int32_t       v4i   __attribute__ ((vector_size(16)));

const v2d v10      = { 1.0, 1.0 };
const v2d v15      = { 1.5, 1.5 };
const v2d v40      = { 4.0, 4.0 };

v2d inv_2n;   // {2.0/N, 2.0/N}


int
GetThreadCount()
{
   cpu_set_t cs;
   CPU_ZERO(&cs);
   sched_getaffinity(0, sizeof(cs), &cs);

   int count = 0;
   for (int i = 0; i < CPU_SETSIZE; ++i)
      count += CPU_ISSET(i, &cs);

   return count;
}


void
mandelbrot(int N, byte* data)
{
   ALIGN int row_processed = 0;

   #pragma omp parallel default(shared) num_threads(GetThreadCount())
   {
      int y = 0;
      while ((y = __sync_fetch_and_add(&row_processed, 1)) < N)
      {
         byte* row_output = data + y * (N >> 3);
         
         v2d Civ = {y, y};
         Civ = Civ * inv_2n - v10;

            for (int x = 0; x < N; x += 2)
            {
            v2d   Crv = {x+1, x};
            Crv = Crv * inv_2n - v15;
            v2d Zrv = Crv;
            v2d Ziv = Civ;
            v2d Trv = Crv * Crv;
            v2d Tiv = Civ * Civ;

            int result = 3; // assume that 2 elements belong to MB set
            int i = 1;

            while ( result && (i++ < 50) )
            {
               v2d ZZ = Zrv * Ziv;
               Zrv = Trv - Tiv + Crv;
               Ziv = ZZ + ZZ + Civ;
               Trv = Zrv * Zrv;
               Tiv = Ziv * Ziv;

               {
                  // trv + tiv <= 4.0
                  v2d delta = v40 - (Trv + Tiv);
                  v4i db = reinterpret_cast<v4i>(delta);
                  
                  const int32_t* pb = reinterpret_cast<const int32_t*>(&db);
                  result = (pb[1] >= 0) | ((pb[3] >= 0) << 1);
               }            
            }

            {
               int bit_shift = 6 - (x & 7);
               row_output[x >> 3] |= static_cast<byte>(result << bit_shift);
            }
         }
      }
   }
}


int
main (int argc, char **argv)
{
   const int N = (argc == 2) ? std::atoi(argv[1]) : 200;
   assert((N % 8) == 0);
   printf("P4\n%d %d\n", N, N);

   {
      double* p_iv = reinterpret_cast<double*>(&inv_2n);
      p_iv[0] = p_iv[1] = 2.0 / N;
   }

   const int bytes_count = (N >> 3) * N;
   byte* data = 0;
   assert(   posix_memalign(reinterpret_cast<void**>(&data), L2_CACHE_LINE, bytes_count)
         == 0);
   memset(data, 0, bytes_count);

   mandelbrot(N, data);

   fwrite( data, bytes_count, 1, stdout);
   fflush(stdout);
   free(data);

   return 0;
}

 make, command-line, and program output logs

Mon, 28 Oct 2013 18:37:49 GMT

MAKE:
/usr/bin/g++ -c -pipe -O3 -fomit-frame-pointer -march=native -mfpmath=sse -msse2 -fopenmp -mfpmath=sse -msse2 mandelbrot.gpp-6.c++ -o mandelbrot.gpp-6.c++.o &&  \
        /usr/bin/g++ mandelbrot.gpp-6.c++.o -o mandelbrot.gpp-6.gpp_run -fopenmp 
rm mandelbrot.gpp-6.c++
0.20s to complete and log all make actions

COMMAND LINE:
./mandelbrot.gpp-6.gpp_run 16000

(BINARY) PROGRAM OUTPUT NOT SHOWN

Revised BSD license

  Home   Conclusions   License   Play