Skip to content

Image Softening Benchmark

Hüseyin Tuğrul BÜYÜKIŞIK edited this page Oct 4, 2021 · 13 revisions
#include <iostream>
#include <mutex>
#include <map>
#include <time.h>
#include <math.h>
#include "LruClockCache.h"
int findMandelbrot(double cr, double ci, int max_iterations)
{
    int i = 0;
    double zr = 0.0, zi = 0.0;
    while (i < max_iterations && zr * zr + zi * zi < 4.0)
    {
        double temp = zr * zr - zi * zi + cr;
        zi = 2.0 * zr * zi + ci;
        zr = temp;
        ++i;
    }
    return i;
}

double mapToReal(int x, int imageWidth, double minR, double maxR)
{
    double range = maxR - minR;
    return x * (range / imageWidth) + minR;
}

double mapToImaginary(int y, int imageHeight, double minI, double maxI)
{
    double range = maxI - minI;
    return y * (range / imageHeight) + minI;
}

int main()
{
        // mandelbrot generation + (softening X10) using a cache

	using namespace std;

	std::map<int,int> map;

	
	int imageWidth, imageHeight, maxN;
	double minR, maxR, minI, maxI;

	 
        imageWidth=1024;
        imageHeight=1024;
        maxN=512;
        minR=-1.5;
        maxR=0.7;
        minI=-1.0;
        maxI=1.0;

		size_t readmiss=0;
		size_t writemiss=0;
		size_t read=0;
		size_t write=0;
		LruClockCache<int,int> cache(1024*1024,
					[&](int key){ readmiss++; return map[key];},
					[&](int key,int value){ writemiss++; map[key]=value; });

	    ofstream g("output_image.ppm");
	    g << "P6" << endl;
	    g << imageWidth << " " << imageHeight << endl;
	    g << "255" << endl;


	    double start = clock();
	    double t = 0;

	    for (int i = 0; i < imageHeight; i++)
	    {
	        for (int j = 0; j < imageWidth; j++)
	        {
	            double cr = mapToReal(j, imageWidth, minR, maxR);
	            double ci = mapToImaginary(i, imageHeight, minI, maxI);
	           
	            cache.set(i+j*imageWidth, findMandelbrot(cr, ci, maxN));
	          
	            read++;
	        }
	    }


	    for(int k=0;k<10;k++)
	    {
		    for (int i = 1; i < imageHeight-1; i++)
		    {
		        for (int j = 1; j < imageWidth-1; j++)
		        {
		            double cr = mapToReal(j, imageWidth, minR, maxR);
		            double ci = mapToImaginary(i, imageHeight, minI, maxI);
		        
		            int n0 = cache.get(i+j*imageWidth);
		            int n1 = cache.get(i+1+j*imageWidth);
		            int n2 = cache.get(i-1+j*imageWidth);
		            int n3 = cache.get(i+(j+1)*imageWidth);
		            int n4 = cache.get(i+(j-1)*imageWidth);
		            int n = (n0+n1+n2+n3+n4)/5.0;
		            cache.set(i+j*imageWidth,n);
		      
		            read+=5;
		            write++;
		        }
		    }

	    }

	    for (int i = 0; i < imageHeight; i++)
	    {
	        for (int j = 0; j < imageWidth; j++)
	        {
	        
	        	int n = cache.get(i+j*imageWidth);
	        
	            int r = ((int)sqrt(n) % 256);
	            int gr = (2*n % 256);
	            int b = (n % 256);
	            write++;
	            g << (char)r << (char)gr << (char)b ;
	        }

	    }
	    cout << "Finished!" << endl;


	    double stop = clock();

	    cout << (stop-start)/CLOCKS_PER_SEC;
	  
	    cache.flush();
	  
	    g.flush();

	    cout <<endl << t << endl;
	    std::cout<< (read-readmiss)/(double)read<<std::endl;
	    std::cout<< (write-writemiss)/(double)write<<std::endl;
		return 0;
}

FX8150: 3.2 seconds (~19.5 million pixels per second)

https://www.codechef.com/ide: 2.3 seconds (~27.5 million pixels per second)

Clone this wiki locally