Вот код, который я обычно использую для получения совмещенной памяти с Visual Studio и GCC
inline void* aligned_malloc(size_t size, size_t align) {
void *result;
#ifdef _MSC_VER
result = _aligned_malloc(size, align);
#else
if(posix_memalign(&result, align, size)) result = 0;
#endif
return result;
}
inline void aligned_free(void *ptr) {
#ifdef _MSC_VER
_aligned_free(ptr);
#else
free(ptr);
#endif
}
Является ли этот код в целом вообще? Я также видел, как люди использовали _mm_malloc
, _mm_free
. В большинстве случаев я хочу, чтобы выровненная память использовала SSE/AVX. Могу ли я использовать эти функции в целом? Это сделает мой код намного проще.
Наконец, легко создать мою собственную функцию для выравнивания памяти (см. ниже). Почему тогда существует так много разных общих функций для получения согласованной памяти (многие из которых работают только на одной платформе)?
Этот код выполняет выравнивание по 16 байт.
float* array = (float*)malloc(SIZE*sizeof(float)+15);
// find the aligned position
// and use this pointer to read or write data into array
float* alignedArray = (float*)(((unsigned long)array + 15) & (~0x0F));
// dellocate memory original "array", NOT alignedArray
free(array);
array = alignedArray = 0;
Смотрите: http://www.songho.ca/misc/alignment/dataalign.html и Как выделить выровненную память только с помощью стандартной библиотеки?
Изменить: В случае, если кто-то заботится, я получил идею моей функции aligned_malloc() от Eigen (Eigen/src/Core/util/Memory.h)
Изменить:
Я только что обнаружил, что posix_memalign
- undefined для MinGW. Тем не менее, _mm_malloc
работает для Visual Studio 2012, GCC, MinGW и компилятора Intel С++, поэтому, похоже, это наиболее удобное решение в целом. Он также требует использования собственной функции _mm_free
, хотя на некоторых реализациях вы можете передавать указатели от _mm_malloc
до стандартного free
/delete
.