OSX отсутствует memalign
Я работаю над проектом на C, и для него требуется memalign(). Действительно, posix_memalign() будет делать то же самое, но darwin/OSX не хватает обоих.
Что такое хорошее решение для shoehorn-in memalign? Я не понимаю лицензирования для кода posix-C, если бы я должен был разорвать memalign.c и поместить его в мой проект - я не хочу, чтобы лицензия на вирусное лицензирование LGPL-ing на весь мой проект.
Ответы
Ответ 1
Mac OS X выглядит как 16-байт mem aligned.
Цитата с сайта:
Мне было трудно найти окончательный инструкции по выравниванию памяти MacOS X поэтому я сделал свои собственные тесты. На 10.4/intel, как стек, так и куча памяти - 16 байт выровнены. Поэтому люди портируют программное обеспечение может перестать искать memalign() и posix_memalign(). Его не нужно.
Ответ 2
Должно быть достаточно легко сделать себя, нет? Что-то вроде следующего (не проверено):
void *aligned_malloc( size_t size, int align )
{
void *mem = malloc( size + (align-1) + sizeof(void*) );
char *amem = ((char*)mem) + sizeof(void*);
amem += align - ((uintptr)amem & (align - 1));
((void**)amem)[-1] = mem;
return amem;
}
void aligned_free( void *mem )
{
free( ((void**)mem)[-1] );
}
(спасибо Джонатан Леффлер)
Edit:
Что касается копирования другой memalign реализации, проблема с этим не лицензирование. Скорее всего, вы столкнулись с трудностями в том, что любая хорошая реализация memalign станет неотъемлемой частью кодовой базы кучи-менеджера, а не просто накладывается поверх malloc/free. Таким образом, у вас возникнут серьезные проблемы с пересадкой его на другого кучного менеджера, особенно если у вас нет доступа к нему внутри.
Ответ 3
обновление: OSX теперь имеет posix_memalign()
Поздно к партии, но более новые версии OSX имеют posix_memalign()
. Это может потребоваться при выравнивании по границам страницы. Например:
#include <stdlib.h>
char *buffer;
int pagesize;
pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == -1) handle_error("sysconf");
if (posix_memalign((void **)&buffer, pagesize, 4 * pagesize) != 0) {
handle_error("posix_memalign");
}
Следует отметить, что в отличие от memalign()
, posix_memalign()
принимает **buffer
в качестве аргумента и возвращает целочисленный код ошибки.
Ответ 4
Почему программное обеспечение, которое вы переносите, требует memalign() или posix_memalign()? Использует ли он его для выравниваний больше, чем 16-байтовые выравнивания, на которые ссылается austirg?
Я вижу, что Mike F опубликовал некоторый код - он выглядит довольно аккуратно, хотя я думаю, что цикл while может быть субоптимальным (если требуемое выравнивание равно 1 Кбайт, оно может повторяться несколько раз).
не
amem += align - ((uintptr)amem & (align - 1));
попасть туда за одну операцию?
Ответ 5
На страницах руководства macosx:
malloc(), calloc(), valloc(), realloc() и reallocf() выделить память. Выделенная память выравнивается так, что она может быть используется для любого типа данных, включая типы AltiVec- и SSE. Свобода() функция освобождает распределения, которые были созданы с помощью предыдущего выделения функции.
Ответ 6
Да Mac OS X имеет 16-ю байтовую привязку памяти в ABI.
Вам не нужно использовать memalign(). Если ваши требования к памяти являются фактором 16, я бы не реализовал его и, возможно, просто добавил assert.
Ответ 7
Если вам нужен произвольно выровненный malloc, проверьте x264 malloc (common/common.c в репозитории git), который имеет пользовательский memalign для систем без malloc.h. Его чрезвычайно тривиальный код, до такой степени, что я даже не считаю его защищенным авторским правом, но вы можете легко реализовать его после просмотра.
Конечно, если вам нужно только 16-байтовое выравнивание, как указано выше, его в OS X ABI.
Ответ 8
Возможно, вам стоит предложить использовать Doug Lea malloc в вашем коде. текст ссылки
Ответ 9
Спасибо за помощь, ребята... помогли в моем случае (OpenCascade src/Image/Image_PixMap.cxx, OSX10.5.8 PPC)
В сочетании с вышеприведенными ответами, это может спасти кого-то, кто копает или придает надежду, если не особенно знаком с malloc и т.д.:
В довольно большом проекте, который я создаю, была только ссылка на posix_memalign, и, оказывается, это было результатом множества условий препроцессора, которые не включали OSX, но DID включают BORLANDC, что подтверждает то, что другие предложили об этом в некоторых случаях безопасно использовать malloc:
#if defined(_MSC_VER)
return (TypePtr )_aligned_malloc (theBytesCount, theAlign);
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
return (TypePtr ) _mm_malloc (theBytesCount, theAlign);
#elif defined(__BORLANDC__)
return (TypePtr ) malloc (theBytesCount);
#else
void* aPtr;
if (posix_memalign (&aPtr, theAlign, theBytesCount))
{
aPtr = NULL;
}
return (TypePtr )aPtr;
#endif
Итак, это может быть так просто, как просто использовать malloc, как это было предложено другими.
например. здесь: перемещение __BORLANDC__
выше __GNUC__
и добавление APPLE:
#elif (defined(__BORLANDC__) || defined(__APPLE__)) //now above `__GNUC__`
ПРИМЕЧАНИЕ. Я НЕ проверял, что BORLANDC использует выравнивание по 16 байт, как это сделал вышеописанный OS X. Я также не проверял, что PPC OS X делает. Однако это использование говорит о том, что это выравнивание не имеет особого значения. (Здесь надеются, что это сработает, и что это может быть так легко для вас, искателей!)