mandelbrot C gcc #5 program
source code
/* The Computer Language Benchmarks Game
http://benchmarksgame.alioth.debian.org/
contributed by Ralph Ganszky
modified for Swift 3.0 by Daniel Muellenborn
modified for C & gcc by Dominic Letz
Compile with: gcc -O3 -mno-fma -march=native -fopenmp main.c
*/
#include <stdio.h>
#include <stdlib.h>
int Iter = 50;
typedef double Vec __attribute__ ((vector_size(32)));
const int Vec__size = sizeof(Vec)/sizeof(double);
typedef unsigned char Byte;
int bt(Vec lhs, double rhs) {
for (int i = 0; i < Vec__size; i++)
if (lhs[i] <= rhs)
return 0;
return 1;
}
// Calculate mandelbrot set for one Vec into one byte
Byte mand(Vec cr, Vec ci) {
Vec Zr = {0.0};
Vec Zi = {0.0};
Vec Tr = {0.0};
Vec Ti = {0.0};
for (int i = 0; i < Iter/5; i++) {
for (int j = 0; j < 5; j++) {
Zi = (Zr + Zr) * Zi + ci;
Zr = Tr - Ti + cr;
Tr = Zr * Zr;
Ti = Zi * Zi;
}
if (bt(Tr + Ti, 4.0)) {
return 0;
}
}
Byte byte = 0;
Vec t = Tr + Ti;
for (int i = 0; i < Vec__size; i++) {
byte |= t[i] <= 4.0 ? (0x80 >> i) : 0;
}
return byte;
}
// Parse command line arguments
int main(int argc, char* argv[])
{
int n = (argc > 1) ? atoi(argv[1]) : 200;
int N = (n + Vec__size - 1) & ~(Vec__size - 1);
double inv = 2.0 / ((double)n);
Vec xvals[N/Vec__size];
Vec yvals[N];
Byte *rows = malloc(n*N/8);
for (int i = 0; i < N; i++) {
xvals[i/Vec__size][i%Vec__size] = ((double)i) * inv - 1.5;
for (int j = 0; j < Vec__size; j++) {
yvals[i][j] = ((double)i) * inv - 1.0;
}
}
#pragma omp parallel for schedule(guided)
for (int y = 0; y < n; y++) {
for (int x = 0; x < N/Vec__size; x+=8/Vec__size) {
Byte b = 0;
for (int v = 0; v < 8/Vec__size; v++) {
b |= mand(xvals[x + v], yvals[y]) >> (v*Vec__size);
}
rows[y*N/8+x/(8/Vec__size)] = b;
}
}
FILE* out = (argc == 3) ? fopen(argv[2], "wb") : stdout;
fprintf(out, "P4\n%u %u\n", n, n);
fwrite(&rows[0], n*N/8, 1, out);
if (out != stdout)
{
fclose(out);
}
free(rows);
return 0;
}
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
gcc (Ubuntu 14.2.0-4ubuntu2) 14.2.0
Tue, 22 Oct 2024 19:08:13 GMT
MAKE:
/usr/bin/gcc -pipe -Wall -O3 -fomit-frame-pointer -march=ivybridge -fopenmp mandelbrot.gcc-5.c -o mandelbrot.gcc-5.gcc_run
rm mandelbrot.gcc-5.c
2.53s to complete and log all make actions
COMMAND LINE:
./mandelbrot.gcc-5.gcc_run 16000
(BINARY) PROGRAM OUTPUT NOT SHOWN