M-am lovit recent de nevoia de a aloca memorie aliniata la 16 octeti (standard pentru instructiuni SSE). Cum am gasit multe variante, implementari si solutii pe Internet (pe *nix exista functii, pe Windows existau), am incercat sa creez o varianta independenta de platforma care sa poata fi reutilizata usor. Apelurile la cele doua functii aligned_alloc si aligned_free pot fi inlocuite usor cu malloc/free cu aceeasi functionalitate. Eu am testat codul sub Windows/Visual C++ 2008, a functionat OK, postez aici si astept sugestii / imbunatatiri... dupa ce ne asiguram ca merge intr-adevar bine pe mai multe sisteme/compilatoare il putem adauga si la snippets:
-
-
- void* aligned_alloc(unsigned int number_of_bytes, unsigned int alignment)
- {
- #ifdef _MSC_VER
- //we do not use aligned_malloc since MSDN documentation says it is incompatible with post-XP Windows
- unsigned int displacement;
- char *tempbuffer = (char *)malloc (number_of_bytes + sizeof(int) + alignment - 1);
- assert(tempbuffer != NULL);
-
- //tempbuffer is displaced by sizeof(int) since we'll always store the total displacement just before the beginning of the buffer, regardless of address
- tempbuffer += sizeof(int) + alignment - 1;
- displacement = (unsigned int)tempbuffer % alignment;
- //calculate final buffer start address
- tempbuffer -= displacement;
-
- //store the total displacement size just before the allocated buffer
- *( (unsigned int *) (tempbuffer - sizeof(int)) ) = sizeof(int) + alignment - 1 - displacement;
- return tempbuffer;
-
- #else
- //*Nix systems _usually_ have memalign; use that on such platforms
- return memalign(alignment, number_of_bytes);
- #endif
- }
-
- void aligned_free(void *buffer)
- {
- #ifdef _MSC_VER
- //if buffer was created using aligned_alloc, the sizeof(int) bytes before it hold a displacement value disp
- //disp represents the number of positions skipped from the address returned by malloc in aligned_alloc
- char *aux = (char *)buffer;
- unsigned int disp;
- disp = *( (unsigned int *) (aux - sizeof(int)) );
- aux -= disp;
- free(aux);
- buffer = NULL;
- #else
- free(buffer);
- #endif
- }
-
-