Click here to Skip to main content
15,896,539 members
Articles / Programming Languages / C++

Generating Fractals with SSE/SSE2

Rate me:
Please Sign up or sign in to vote.
4.94/5 (94 votes)
29 Nov 2005CPOL32 min read 450.7K   2.5K   87  
An article on generating Mandelbrot and Julia sets using Intel's Streaming SIMD Extensions (SSE, SSE2).
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
//#include <math.h>
#include "resource.h"
#include <limits.h>
#include <crtdbg.h>
#include <stdlib.h>
#include <ddraw.h>
#include <assert.h>

#ifndef _DEBUG
#pragma comment(linker, "/ENTRY:WinMain")
#pragma comment(linker,"/merge:.rdata=.text")
#endif
extern "C" int _fltused = 0;

#ifdef UNICODE
#define cmp2ch(s,a,b) (*(long*)(s) == \
	((unsigned short)(a) | (unsigned short)(b) << 16))
#define cmp4ch(s,a,b,c,d) (*(long*)(s) == \
	((unsigned short)(a) | (unsigned short)(b) << 16) && \
	*(long*)(s+2) == \
	((unsigned short)(c) | (unsigned short)(d) << 16))
#define set2ch(s,a,b) (*(long*)(s) = \
	((unsigned short)(a) | (unsigned short)(b) << 16));
#define set4ch(s,a,b,c,d) (*(long*)(s) = \
	((unsigned short)(a) | (unsigned short)(b) << 16), \
	*(long*)(s+2) = \
	((unsigned short)(c) | (unsigned short)(d) << 16));
#else
#define cmp2ch(s,a,b) (*(short*)(s) == \
	((unsigned char)(a) | (unsigned char)(b) << 8))
#define cmp4ch(s,a,b,c,d) (*(long*)(s) == \
	 ((unsigned char)(a) | (unsigned char)(b) << 8 |   \
     (unsigned char)(c) << 16 | (unsigned char)(d) << 24))
#define set2ch(s,a,b) (*(short*)(s) = \
	((unsigned char)(a) | (unsigned char)(b) << 8));
#define set4ch(s,a,b,c,d) (*(long*)(s) = \
	 ((unsigned char)(a) | (unsigned char)(b) << 8 |   \
     (unsigned char)(c) << 16 | (unsigned char)(d) << 24));
#endif

HANDLE heap;
SYSTEM_INFO si;
int inline ceil(const int i, const int power2) {
	return (i + power2 - 1) & -power2;
}
/*int inline floor(const int i, const int power2) {
	return i & -power2;
}*/
inline long* ceil(const void* i, const int power2) {
	return (long*)(((const int)i + power2 - 1) & -power2);
}
//#ifndef _DEBUG
size_t oldsize=0;
void __forceinline *malloc2(size_t n) { // Memory allocation and freeing
	//return HeapAlloc(heap, HEAP_NO_SERIALIZE, n);
	void* mem = VirtualAlloc(NULL, ceil(n, si.dwPageSize), MEM_COMMIT, PAGE_READWRITE);
	if(!mem) {
		MessageBox(0, TEXT("Out of memory"), TEXT("Fractals"), MB_ICONERROR);
		ExitProcess(1);
	}
	return mem;
}
#define malloc(a) malloc2(a)
// WARNING: that's a special case of the fast memory reallocator for this application only;
// the realloc() function won't work in other circumstances!
// Use commented out version with HeapAlloc/HeapRealloc/HeapFree instead.
void __forceinline *realloc2(void* p, size_t n) {
	if(n > oldsize) {
		VirtualFree(p, 0, MEM_RELEASE);
		oldsize = ceil(n, si.dwPageSize);
		void* mem = VirtualAlloc(NULL, oldsize, MEM_COMMIT, PAGE_READWRITE);
		if(!mem) {
			MessageBox(0, TEXT("Out of memory"), TEXT("Fractals"), MB_ICONERROR);
			ExitProcess(1);
		}
		return mem;
	}
	return p;
	//if (p == NULL) return malloc(n);
    //return HeapReAlloc(heap, HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, p, n);
}
#define realloc(a, b) realloc2(a, b)
void __forceinline free2(void* p) {
	VirtualFree(p, 0, MEM_RELEASE);
    //if (p == NULL) return;
    //HeapFree(heap, HEAP_NO_SERIALIZE, p);
}
#define free(n) free2(n)
//#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Czech Republic Czech Republic
Peter is the developer of Aba Search and Replace, a tool for replacing text in multiple files. He likes to program in C with a bit of C++, also in x86 assembly language, Python, and PHP.

Comments and Discussions