OSX не хватает memalign - PullRequest
       12

OSX не хватает memalign

13 голосов
/ 13 октября 2008

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

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

Ответы [ 9 ]

13 голосов
/ 13 октября 2008

Mac OS X выглядит как выровненный по 16 байтам.

Цитата с сайта:

Мне было трудно найти окончательный заявление о выравнивании памяти MacOS X поэтому я сделал свои собственные тесты. На 10.4 / intel, и память стека и кучи составляет 16 байт выровнены. Так люди портируют софт может перестать искать memalign () и posix_memalign (). Это не нужно.

8 голосов
/ 05 апреля 2014

обновление: OSX теперь имеет posix_memalign()

Поздно на вечеринке, но более новые версии OSX do имеют 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 и возвращает целочисленный код ошибки.

6 голосов
/ 13 октября 2008

Должно быть достаточно легко сделать самому, нет? Что-то вроде следующего (не проверено):

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 будет неотъемлемой частью базы кода heap-manager, а не просто размещена поверх malloc / free. Таким образом, у вас возникнут серьезные проблемы с переносом его другому менеджеру кучи, особенно если у вас нет доступа к его внутренним компонентам.

3 голосов
/ 13 октября 2008

Зачем портируемому программному обеспечению требуется memalign () или posix_memalign ()? Использует ли он его для выравниваний, превышающих 16-байтовые выравнивания, на которые ссылается austirg?

Я вижу, что Майк F опубликовал некоторый код - он выглядит относительно аккуратно, хотя я думаю, что цикл while может быть неоптимальным (если требуемое выравнивание составляет 1 КБ, оно может повторяться довольно много раз).

не делает:

amem += align - ((uintptr)amem & (align - 1));

попасть туда за одну операцию?

2 голосов
/ 13 октября 2008

со страниц справочника macosx:

malloc (), calloc (), valloc (), Функции realloc () и reallocf () выделить память. Выделенная память выровнена так, что она может быть используется для любого типа данных, включая типы, связанные с AltiVec и SSE. Свобода() функция освобождает выделения, которые были созданы с помощью предыдущего выделения функции.

1 голос
/ 03 марта 2009

Может быть стоит предложить использовать malloc Дуга Ли в вашем коде. текст ссылки

1 голос
/ 13 октября 2008

Если вам нужен произвольно выровненный malloc, проверьте malloc x264 (common / common.c в репозитории git), который имеет собственный memalign для систем без malloc.h. Это чрезвычайно тривиальный код, до такой степени, что я даже не считаю его защищенным авторским правом, но вы легко сможете реализовать свой собственный, увидев его.

Конечно, если вам нужно только 16-байтовое выравнивание, как указано выше, это в OS X ABI.

1 голос
/ 13 октября 2008

Да Mac OS X имеет 16-байтовое выравнивание памяти в ABI . Вам не нужно использовать memalign (). Если у вас требования к памяти в 16 раз, я бы не стал реализовывать это и, возможно, просто добавил бы утверждение.

0 голосов
/ 29 января 2013

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...