-
Notifications
You must be signed in to change notification settings - Fork 5
Image Softening Benchmark
Hüseyin Tuğrul BÜYÜKIŞIK edited this page Oct 20, 2021
·
13 revisions
#include <iostream>
#include <fstream>
#include <mutex>
#include <map>
#include <time.h>
#include <math.h>
#include "LruClockCache.h"
// Mandelbrot set from stackoverflow
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",ios::binary);
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++;
}
}
// image softening (may not be accurate)
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: 2.2 seconds (~28 million pixels per second)
https://www.codechef.com/ide: 2.3 seconds (~27.5 million pixels per second) (old version)
http://cpp.sh: 2.2 seconds (28 million pixels per second)(old version)
https://www.tutorialspoint.com/compile_cpp_online.php: 8.8 seconds(old version)
https://www.programiz.com/cpp-programming/online-compiler: 17 seconds(old version)