Зачем использовать mm malloc? (в отличие от выравниваются Танос, ассоциировала к alloc, или memalign в POSIX )
есть несколько вариантов для получения выровненного блока памяти, но они очень похожи, и проблема в основном сводится к тому, на какой стандарт языка и платформы вы ориентируетесь.
C11
void * aligned_alloc (size_t alignment, size_t size)
POSIX
int posix_memalign (void **memptr, size_t alignment, size_t size)
Windows
void * _aligned_malloc(size_t size, size_t alignment);
и, конечно, это также всегда возможность выравнивания вручную.
Intel предлагает другой вариант.
корпорация Intel
void* _mm_malloc (int size, int align)
void _mm_free (void *p)
на основе исходного кода, выпущенного Intel, это, кажется, метод выделения выровненной памяти, которую предпочитают их инженеры, но я не могу найти никакой документации, сравнивающей ее с другими методами. Ближайший, который я нашел, просто признает, что существуют другие выровненные процедуры выделения памяти.
для динамического выделения части выровненной памяти используйте posix_memalign, который поддерживается GCC, а также компилятором Intel. Выгода его использование заключается в том, что вам не нужно менять API утилизации памяти. Вы можете использовать free() как всегда. Но обратите внимание на профиль параметра:
int posix_memalign (void * * memptr, size_t align, size_t size);
компилятор Intel также предоставляет другой набор выделения памяти Апис. Программисты C / C++ могут использовать _mm_malloc и _mm_free для выделения и бесплатно выровненные блоки памяти. Например, следующее оператор запрашивает 64-байтовый выровненный блок памяти для 8 с плавающей запятой элементы.
farray = (float *)_ _ mm _ malloc(8*sizeof(float), 64);
память, выделенная с помощью _mm_malloc, должна быть освобождена с помощью _mm_free. Вызов free в памяти, выделенной _mm_malloc, или вызов _mm_free в памяти, выделенной malloc, приведет к непредсказуемому поведению.
явные различия с точки зрения пользователя это _mm_malloc
требуется прямая поддержка процессора и компилятора и память, выделенная с _mm_malloc
должен быть освобожден с _mm_free
. Учитывая эти недостатки, в чем причина использования_mm_malloc?
может ли он иметь небольшое преимущество в производительности? Историческая случайность?
3 ответов
компиляторы Intel поддерживают операционные системы POSIX (Linux) и non-POSIX (Windows), следовательно, не могут полагаться ни на POSIX, ни на функцию Windows. Таким образом, было выбрано специфичное для компилятора, но ОС-агностическое решение.
C11-отличное решение, но Microsoft еще не поддерживает C99, поэтому кто знает, будут ли они когда-либо поддерживать C11.
обновление: в отличие от функций распределения C11/POSIX/Windows, встроенные ICC включают функцию освобождения. Это позволяет этому API использовать отдельный менеджер кучи от менеджера по умолчанию. Я не знаю, действительно ли/когда это происходит, но может быть полезно поддерживать эту модель.
отказ от ответственности: я работаю на Intel, но не имею специальных знаний об этих решениях, которые произошли задолго до того, как я присоединился к компании.
можно взять существующий компилятор C, который в настоящее время не использует идентификаторы _mm_alloc
и _mm_free
и определить функции с теми именами, которые будут вести себя так, как требуется. Это может быть сделано либо с помощью_mm_alloc
функция как обертка на malloc()
который запрашивает слегка негабаритное распределение и создает указатель на первый соответствующим образом выровненный адрес внутри него, который составляет по крайней мере один байт с самого начала, и сохраняет количество байтов, пропущенных сразу до этого адреса, или _mm_malloc
запрос большие куски памяти из malloc()
и затем распределить их по частям. В любом случае, указатели возвращаются _mm_malloc()
не было бы указателей, что free()
обычно знает, как что-то делать с; вызов _mm_free
будет использовать байт, непосредственно предшествующий распределению, в качестве помощи для поиска реального начала распределения, полученного от malloc
, а потом проходят, Что делать free
.
если функция aligned-allocate разрешена использовать внутренности malloc
и free
функции, однако, которые могут исключить потребность для дополнительного слоя оборачивать. Можно написать _mm_alloc()
/_mm_free()
функции, которая оборачивает malloc
/free
ничего не зная о своих внутренних органах, но это требует этого _mm_alloc()
держите бухгалтерскую информацию, которая отделена от того, что используется malloc
/free
.
если автор функции aligned-allocate знает, как malloc
и free
несколько реализовано, часто можно будет координировать дизайн всех функций распределения / свободных так, что free
может различать все виды распределений и обрабатывать их соответствующим образом. Ни одна реализация aligned-allocate не будет использоваться для всех malloc
/free
однако реализаций.
я бы предположил, что самый портативный способ написать код, вероятно, будет выбрать пару символов, которые не используются нигде больше для вашего собственного выделения и бесплатно функции, так что вы могли бы сказать, например,
#define a_alloc(align,sz) _mm_alloc((align),(sz))
#define a_free(ptr) _mm_free((ptr))
на компиляторы, которые поддерживают это, или
static inline void *aa_alloc(int align, int size)
{
void *ret=0;
posix_memalign(&ret, align, size); // Guessing here
return ret;
}
#define a_alloc(align,sz) aa_alloc((align),(sz))
#define a_free(ptr) free((ptr))
на системах Posix и т. д. Для каждой системы должно быть возможно определить макросы или функции, которые дадут необходимое поведение [я думаю, что, вероятно, лучше использовать макросы последовательно, чем иногда использовать макросы и иногда функции, чтобы разрешить #if defined macroname
чтобы проверить, определены ли вещи еще].
_mm_malloc, похоже, был создан до того, как появилась стандартная функция aligned_alloc, и необходимость использования _mm_free является причудой реализации.
Я предполагаю, что в отличие от использования posix_memalign, ему не нужно чрезмерно выделять, чтобы гарантировать выравнивание, вместо этого он использует отдельный распределитель с учетом выравнивания. Это позволит сэкономить память при выделении различных типов с выравниванием выравнивание по умолчанию (обычно 8 или 16 байт).