2015-06-08 6 views
2

Когда calloc используется указатели на вновь выделенную память, выровнены по меньшей мере с числовым числом наименее значимых бит, что означает, что наименее значимые биты (как помеченные указатели) могут использоваться для блокировки, свободных алгоритмов, и на самом деле обычно используется в случае этих алгоритмов. Я тестировал функцию памяти на сервере linux ubuntu (x86_64 GNU/Linux, 3.10.23-xxxx-std-ipv6-64-vps), и из моих экспериментов кажется, что для 4 младших значащих бит установлено значение 0. Из то, что я прочитал, указывает, что выравнивание указателя формируется таким образом, чтобы указатель, выраженный как uintptr, был разделен на 4 (выравнивание до 2 младших значащих бит)Выравнивание указателей для алгоритмов блокировки

Каково минимальное количество наименее значимых бит в недавно выделенных указатели памяти, полученные из системы управления памятью в POSIX (linux), которые всегда устанавливаются в 0 во время процесса выделения первичной памяти?

Каково максимальное количество наименее значимых битов, которые могут использоваться как тегированные указатели на Linux-системах (например, алгоритмы блокировки)?

Как заставить компилятор выровнять новые выделенные указатели, чтобы вывести число наименее значимых бит?

Является ли выравнивание указателей влияющим на общую производительность системы и как?

+0

Там нет «минимум» или «максимальное» число младших значащих битов, которые установлены на 0. Выравнивание памяти зависит от платформы. Все, что вы знаете, это то, что система обычно имеет один тип, который ограничивает выравнивание памяти, и что 'malloc()' и другие функции выделения памяти всегда возвращают указатель, который соответствующим образом выровнен для самого строгого типа (и, следовательно, может использоваться с любым типом) –

+0

И почему вы думаете, что существует связь между выравниванием памяти и алгоритмами блокировки? –

+0

Я думаю, вы, возможно, захотите прочитать http://man7.org/linux/man-pages/man3/posix_memalign.3.html. Обычно выравнивание памяти основано на sizeof (double). Если вы вызываете функции на страницах руководства, его можно изменить. –

ответ

2

Я боюсь, что я не могу ответить на весь ваш вопрос, но я могу сделать старт:

выравнивание указателя может не только производительность, но и изменения, необходимые, чтобы сделать ваш код работать на всех. Специально для таких вещей, как процессоры ARM, вы не можете читать числа, превышающие 1 байт, если указатель не выровнен. Это приведет к ошибке.

Если я, например, работаю с большим потоком данных, я предпочитаю, чтобы мои данные были выровнены, поэтому я могу читать больше байтов в одно и то же время, вместо этого нужно читать байт для байта, что будет стоить больше времени/CPU.

2

на x86/x86_64 чтения архитектуры/запись в память выровненной выплачиваются со стоимостью исполнения, потому что вы будете нуждаться в два опе памяти вместо одной одной: операции шины в/из памяти всегда выровнены. На GNU/Linux вы можете использовать posix_memalign & С, чтобы получить кучи выровнен памяти (человек memalign) в пространстве пользователя.

Некоторые компиляторы также поддерживает макрос, чтобы получить выровнены память о стека, например

/* GCC align declarator */ 
#define MYMEMALIGN(x, y) x __attribute__((aligned(y))) 
#endif 

, но я предполагаю, что это не имели портативные решения.

+0

На недавних процессорах Intel штраф за невыложенные нагрузки/магазины равен нулю, за исключением случаев, когда данные пересекают линию кэша. И, возможно, еще больший штраф за пересечение линии страницы. Таким образом, по-прежнему стоит попытаться согласовать ваши данные, но есть хорошая аппаратная поддержка для несвязанных данных для случаев, когда вам нужны разные смещения в ваших данных. –

4

Выравнивание играет важную роль в оптимизации для многих связанных причин:

  • эффективное использование строк кэша
  • избежать отключить упреждающая выборка логик
  • лучшее использование векторных регистров/инструкции (SSE, AVX) ,
  • особенно в случае ввода-вывода, также может быть важно выравнивание страницы памяти.

Вы можете найти очень хорошие ссылки для архитектуры Intel здесь: http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html

быстро отвечая на вопросы:

Что такое минимальное количество значащих битов в недавно выделенной памяти указатели, полученные из системы управления памятью в POSIX (linux), которые всегда установлены в 0 во время начальной памяти процесс распределения?

Это на самом деле зависит от архитектуры процессора/архитектуры, о которой вы говорите.

Какое максимальное количество значащих битов, которые могут быть использованы в качестве меченых указателей на Линукс системах (например, алгоритмы. Безблокировочного)?

же, как бывшие: вы должны использовать std::atomic или boost::atomic для того, чтобы иметь какое-то портативность, если C++ вариант.

На архитектуре Intel память и память памяти являются атомарными для 32 бит, на x86_32, для 64 на x86_64, , если данные правильно выровнены.

Если вы действительно пользуются такой низкий уровень, не забудьте заглянуть в семантике памяти, заборы памяти и так далее («Инструкции Ограждение» в вышеупомянутом руководстве)

+0

Чтобы добавить отличный ответ от @Sigismondo: некоторые инструкции SSE/AVX генерируют ошибку шины, если память не выровнена. – sergico