Блокированные операции и выравнивание с _aligned_malloc

Меня беспокоят операции выравнивания и Interlocked. Очередной раз. В документации для этих функций указано, что переменная, которую мы хотим обновить, должна быть выровнена по 32-битной границе, и что мы можем добиться этого с помощью _aligned_malloc. Отлично.

Итак, у меня есть небольшая тестовая программа:

struct S
{
    char c;
    long l;
}an_S;

printf("%p, %p", (void*)(&(an_S.c)), (void*)(&(an_S.l)));

В режиме выпуска вывод из этого всегда дает мне адрес long, который находится на 4 байта после адреса char, поэтому он начинается на 32-битной границе.

1) Это чисто случайно, или я могу полагаться на это, следовательно, нет необходимости в _aligned_malloc?

2) Если мне нужно использовать aligned_malloc, может кто-нибудь уточнить, как это сделать? Я прочитал документацию на https://msdn.microsoft.com/en-us/library/8z34s9c6.aspx, но, похоже, это не показывает, как присвоить значение памяти, которая `` выделена '' ...

3) (Предполагая, что мне действительно нужен aligned_malloc) Если мне нужен массив структур с длинной переменной, подобной приведенной выше, с которой нужно работать с помощью операции Interlocked, мне нужно добавить какой-то конструктор, чтобы настроить это или есть ли более простой способ сделать это?

4) Я выполнил поиск в Google по запросу _aligned_malloc + interlockedCompareExchange, и он выкупил только 70 результатов. Это говорит мне, что либо большая часть кода, который использует InterlockedCompareExchange (62 800 результатов), либо неверна, либо _aligned_malloc не нужен. Может кто-нибудь уточнить?

_aligned_malloc здесь не нужен. и long l будет выровнен по 4 байтам, если вы не используете #pragma(pack, N), где N меньше 4 (2 или 1). и вообще, исходя из вашего первоначального вопроса, вам нужно абсолютно другое - защита от кратковременного отказа

RbMm 02.05.2018 15:06

На это можно положиться, если использовать выровненные конструкции. Это по умолчанию. Также выравниваются локальные переменные. malloc тоже в порядке. Если вы не хотите необычного выравнивания, например, 16 байт.

David Heffernan 02.05.2018 15:07

Внутри struct S, long l будет на расстоянии X байтов от начала char c, где X - выравнивание struct S. Но это не гарантирует, что экземпляры struct S, такие как an_s, выделяются по выровненным адресам памяти, поэтому l не всегда может находиться на выровненной 32-битной границе. Это зависит от выравнивания, используемого при объявлении struct S, и выравнивания кода, который выделяет struct S.

Remy Lebeau 02.05.2018 23:33

@ Реми Лебо, я в замешательстве. Дэвид Хеффернан говорит ниже, что структуры по умолчанию выровнены. Я не говорю, что вы ошибаетесь, я говорю, что не знаю, что правильно: \ Кроме того, en.wikipedia.org/wiki/Data_structure_alignment сообщает мне Тип каждого члена структуры обычно имеет выравнивание по умолчанию. - значит, если первый член выровнен, все остальные участники после этого будут выровнены?

Wad 03.05.2018 11:37

@Wad, предназначенный для выравнивания По умолчанию. Посмотрите на #pragma pack, alignas и другие подобные директивы компилятора, которые влияют на выравнивание. Подумайте, что происходит, когда структура имеет выравнивание <4 или содержится в другой структуре с выравниванием <4. long l в struct S не будет правильно выровнен для блокированного / атомарного доступа.

Remy Lebeau 03.05.2018 18:24

Ладно, ладно. Итак, пока я придерживаюсь выравнивания по умолчанию и не использую какие-либо из этих директив, я в порядке - правильно?

Wad 03.05.2018 18:52

по раскладу у вас ок. для кода - нет

RbMm 03.05.2018 20:23
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Что касается malloc, документация для MSVC объясняет, что для 32 целей память выровнена по 8 байт, для 64-битных целей она выровнена по 16 байт. Итак, вы можете использовать malloc.

Хорошо, спасибо. Я обсуждал это с коллегой, который предполагает, что причина, по которой MSDN подчеркивает, что переменные должны быть выровнены на 32 бита, заключается в том, что кто-то делает что-то (глупое?), Например, индексирует массив символов и приводит результат как длинный, а затем использует это в функция блокировки; вы бы согласились?

Wad 02.05.2018 15:34

Да, это одна из возможностей. Другой - использование упакованных структур данных.

David Heffernan 02.05.2018 16:19

Другие вопросы по теме