Подтвердить что ты не робот

OSX отсутствует memalign

Я работаю над проектом на C, и для него требуется memalign(). Действительно, posix_memalign() будет делать то же самое, но darwin/OSX не хватает обоих.

Что такое хорошее решение для shoehorn-in memalign? Я не понимаю лицензирования для кода posix-C, если бы я должен был разорвать memalign.c и поместить его в мой проект - я не хочу, чтобы лицензия на вирусное лицензирование LGPL-ing на весь мой проект.

4b9b3361

Ответ 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 делает. Однако это использование говорит о том, что это выравнивание не имеет особого значения. (Здесь надеются, что это сработает, и что это может быть так легко для вас, искателей!)