ݺߣ

ݺߣShare a Scribd company logo
Урок 21. Паттерн 13. Выравнивание
данных
Процессоры работают эффективнее, когда имеют дело с правильно выровненными данными. А
некоторые процессоры вообще не умеют работать с не выровненными данными. Попытка
работать с не выровненными данными на процессорах IA-64 (Itanium), как показано в следующем
примере, приведет к возникновению исключения:

#pragma pack (1) // Also set by key /Zp in MSVC

struct AlignSample {

    unsigned size;

    void *pointer;

} object;

void foo(void *p) {

    object.pointer = p; // Alignment fault

}

Если вы вынуждены работать с не выровненными данными на Itanium, то следует явно указать это
компилятору. Например, воспользоваться специальным макросом UNALIGNED:

#pragma pack (1) // Also set by key /Zp in MSVC

struct AlignSample {

    unsigned size;

    void *pointer;

} object;

void foo(void *p) {

    *(UNALIGNED void *)&object.pointer = p; //Very slow

}

В этом случае компилятор сгенерирует специальный код, который будет работать с не
выровненными данными. Такое решение неэффективно, так как доступ к данным будет
происходить в несколько раз медленнее. Если целью является уменьшение размера структуры, то
лучшего результата можно достичь, располагая данные в порядке уменьшения их размера.
Подробнее об этом будет рассказано в одном из следующих уроков.

На архитектуре x64 при обращении к не выровненным данным исключения не возникает, но их
также следует избегать. Во-первых, из-за существенного замедления скорости доступа к таким
данным, а во-вторых, из-за возможности переноса программы в будущем на платформу IA-64.
Рассмотрим еще один пример кода, не учитывающий выравнивание данных:

struct MyPointersArray {

  DWORD m_n;

  PVOID m_arr[1];

} object;

...

malloc( sizeof(DWORD) + 5 * sizeof(PVOID) );

...

Если мы хотим выделить объем памяти, необходимый для хранения объекта типа
MyPointersArray, содержащего 5 указателей, то мы должны учесть, что начало массива m_arr
будет выровнено по границе 8 байт. Расположение данных в памяти на разных системах
(Win32/Win64) показано на рисунке 1.




            Рисунок 1- Выравнивание данных в памяти на системах Win32 и Win64

Корректный расчет размера должен выглядеть следующим образом:

struct MyPointersArray {

  DWORD m_n;

  PVOID m_arr[1];

} object;

...
malloc( FIELD_OFFSET(struct MyPointersArray, m_arr) +

          5 * sizeof(PVOID) );

...

В приведенном коде мы узнаем смещение последнего члена структуры и суммируем это
смещение с его размером. Смещение члена структуры или класса можно узнать с использованием
макроса offsetof или FIELD_OFFSET.

Всегда используйте эти макросы для получения смещения в структуре, не опираясь на знание
размеров типов и выравнивания. Пример кода с правильным вычислением адреса члена
структуры:

struct TFoo {

  DWORD_PTR whatever;

  int value;

} object;

int *valuePtr =

  (int *)((size_t)(&object) + offsetof(TFoo, value)); // OK

Разработчиков Linux-приложений может ждать еще одна неприятность, связанная с
выравниванием. О ней вы можете прочитать в нашем блоге в посте "Изменения выравнивания
типов и последствия".


Диагностика
Поскольку работа с не выровненными данными не приводит к ошибке на архитектуре x64, а
только к снижению производительности, инструмент PVS-Studio не предупреждает об
упакованных структурах. Но если для вас критична производительность приложения,
рекомендуем просмотреть все места в программе, где используется "#pragma pack". Для
архитектуры IA-64 данная проверка более актуальна, но анализатор PVS-Studio пока не
ориентирован на верификацию программ для IA-64. Если вы работаете с системами на базе
Itanium и планируете приобрести PVS-Studio, напишите нам, и мы обсудим вопросы адаптации
этого инструмента к особенностям IA-64.

Инструмент PVS-Studio позволяет обнаружить ошибки, связанные с вычислением размеров
объектов и смещений. Анализатор обнаруживает опасные арифметические выражения,
содержащие в себе несколько операторов sizeof(), что свидетельствует о возможной ошибке.
Диагностическое сообщение имеет номер V119.

Однако во многих случаях использование нескольких операторов sizeof() в рамках одного
выражения корректно и анализатор игнорирует подобные конструкции. Пример безопасных
выражений с несколькими операторами sizeof:

int MyArray[] = { 1, 2, 3 };

size_t MyArraySize =
sizeof(MyArray) / sizeof(MyArray[0]); //OK

assert(sizeof(unsigned) < sizeof(size_t)); //OK

size_t strLen = sizeof(String) - sizeof(TCHAR); //OK


Приложение
На рисунке 2 представлены размеры типов и их выравнивание. Для изучения размеров объектов и
их выравнивания на различных платформах вы также можете воспользоваться примером кода,
приведенным в записи блога "Изменения выравнивания типов и последствия".




                       Рисунок 2 - Размеры типов и их выравнивание.
Авторы курса: Андрей Карпов (karpov@viva64.com), Евгений Рыжков (evg@viva64.com).

Правообладателем курса "Уроки разработки 64-битных приложений на языке Си/Си++"
является ООО "Системы программной верификации". Компания занимается разработкой
программного обеспечения в области анализа исходного кода программ. Сайт компании:
http://www.viva64.com.

Контактная информация: e-mail: support@viva64.com, 300027, г. Тула, а/я 1800.

More Related Content

What's hot (12)

машина поста
машина постамашина поста
машина поста
chikisheva90
Урок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаУрок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметика
Tatyanazaxarova
Алгоритмическая конструкция следование
Алгоритмическая конструкция следованиеАлгоритмическая конструкция следование
Алгоритмическая конструкция следование
Andrey Dolinin
алг и прогр (11кл)
алг и прогр (11кл)алг и прогр (11кл)
алг и прогр (11кл)
isva69
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Platonov Sergey
Theme 05
Theme 05Theme 05
Theme 05
pempeshka
Оптимизация в мире 64-битных ошибок
Оптимизация  в мире 64-битных ошибокОптимизация  в мире 64-битных ошибок
Оптимизация в мире 64-битных ошибок
Tatyanazaxarova
Конструирование алгоритмов
Конструирование алгоритмовКонструирование алгоритмов
Конструирование алгоритмов
Andrey Dolinin
Статический анализ и регулярные выражения
Статический анализ и регулярные выраженияСтатический анализ и регулярные выражения
Статический анализ и регулярные выражения
Tatyanazaxarova
Урок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединенияхУрок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединениях
Tatyanazaxarova
Урок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметикаУрок 13. Паттерн 5. Адресная арифметика
Урок 13. Паттерн 5. Адресная арифметика
Tatyanazaxarova
Алгоритмическая конструкция следование
Алгоритмическая конструкция следованиеАлгоритмическая конструкция следование
Алгоритмическая конструкция следование
Andrey Dolinin
алг и прогр (11кл)
алг и прогр (11кл)алг и прогр (11кл)
алг и прогр (11кл)
isva69
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Platonov Sergey
Оптимизация в мире 64-битных ошибок
Оптимизация  в мире 64-битных ошибокОптимизация  в мире 64-битных ошибок
Оптимизация в мире 64-битных ошибок
Tatyanazaxarova
Конструирование алгоритмов
Конструирование алгоритмовКонструирование алгоритмов
Конструирование алгоритмов
Andrey Dolinin
Статический анализ и регулярные выражения
Статический анализ и регулярные выраженияСтатический анализ и регулярные выражения
Статический анализ и регулярные выражения
Tatyanazaxarova
Урок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединенияхУрок 16. Паттерн 8. Memsize-типы в объединениях
Урок 16. Паттерн 8. Memsize-типы в объединениях
Tatyanazaxarova

Similar to Урок 21. Паттерн 13. Выравнивание данных (20)

Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
Tatyanazaxarova
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложений
Tatyanazaxarova
Коллекция примеров 64-битных ошибок в реальных программах
Коллекция примеров 64-битных ошибок в реальных программахКоллекция примеров 64-битных ошибок в реальных программах
Коллекция примеров 64-битных ошибок в реальных программах
Tatyanazaxarova
Что такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_tЧто такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_t
Tatyanazaxarova
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Yandex
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
Andrey Karpov
Как уменьшить вероятность ошибки на этапе написания кода. Заметка N1.
Как уменьшить вероятность ошибки на этапе написания кода. Заметка N1.Как уменьшить вероятность ошибки на этапе написания кода. Заметка N1.
Как уменьшить вероятность ошибки на этапе написания кода. Заметка N1.
Tatyanazaxarova
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложений
OOO "Program Verification Systems"
Разница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомРазница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментом
Tatyanazaxarova
Сравнение диагностических возможностей анализаторов при проверке 64-битного кода
Сравнение диагностических возможностей анализаторов при проверке 64-битного кодаСравнение диагностических возможностей анализаторов при проверке 64-битного кода
Сравнение диагностических возможностей анализаторов при проверке 64-битного кода
Tatyanazaxarova
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-Paste
Tatyanazaxarova
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
Andrey Karpov
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументовУрок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Tatyanazaxarova
Статический анализ Си++ кода
Статический анализ Си++ кодаСтатический анализ Си++ кода
Статический анализ Си++ кода
Tatyanazaxarova
ADD 2011: Статический анализ Си++ кода
ADD 2011: Статический анализ Си++ кодаADD 2011: Статический анализ Си++ кода
ADD 2011: Статический анализ Си++ кода
Andrey Karpov
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
Platonov Sergey
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
Andrey Karpov
PVS-Studio vs Chromium
PVS-Studio vs ChromiumPVS-Studio vs Chromium
PVS-Studio vs Chromium
Tatyanazaxarova
Intel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиIntel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибками
Tatyanazaxarova
Безопасность 64-битного кода
Безопасность 64-битного кодаБезопасность 64-битного кода
Безопасность 64-битного кода
Tatyanazaxarova
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
Tatyanazaxarova
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложений
Tatyanazaxarova
Коллекция примеров 64-битных ошибок в реальных программах
Коллекция примеров 64-битных ошибок в реальных программахКоллекция примеров 64-битных ошибок в реальных программах
Коллекция примеров 64-битных ошибок в реальных программах
Tatyanazaxarova
Что такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_tЧто такое size_t и ptrdiff_t
Что такое size_t и ptrdiff_t
Tatyanazaxarova
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Yandex
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
Andrey Karpov
Как уменьшить вероятность ошибки на этапе написания кода. Заметка N1.
Как уменьшить вероятность ошибки на этапе написания кода. Заметка N1.Как уменьшить вероятность ошибки на этапе написания кода. Заметка N1.
Как уменьшить вероятность ошибки на этапе написания кода. Заметка N1.
Tatyanazaxarova
PVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложенийPVS-Studio, решение для разработки современных ресурсоемких приложений
PVS-Studio, решение для разработки современных ресурсоемких приложений
OOO "Program Verification Systems"
Разница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомРазница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментом
Tatyanazaxarova
Сравнение диагностических возможностей анализаторов при проверке 64-битного кода
Сравнение диагностических возможностей анализаторов при проверке 64-битного кодаСравнение диагностических возможностей анализаторов при проверке 64-битного кода
Сравнение диагностических возможностей анализаторов при проверке 64-битного кода
Tatyanazaxarova
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-Paste
Tatyanazaxarova
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
Andrey Karpov
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументовУрок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Tatyanazaxarova
Статический анализ Си++ кода
Статический анализ Си++ кодаСтатический анализ Си++ кода
Статический анализ Си++ кода
Tatyanazaxarova
ADD 2011: Статический анализ Си++ кода
ADD 2011: Статический анализ Си++ кодаADD 2011: Статический анализ Си++ кода
ADD 2011: Статический анализ Си++ кода
Andrey Karpov
Intel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиIntel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибками
Tatyanazaxarova
Безопасность 64-битного кода
Безопасность 64-битного кодаБезопасность 64-битного кода
Безопасность 64-битного кода
Tatyanazaxarova

More from Tatyanazaxarova (18)

Урок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окруженияУрок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окружения
Tatyanazaxarova
Урок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программУрок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программ
Tatyanazaxarova
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибокУрок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Tatyanazaxarova
Урок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. ИсключенияУрок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. Исключения
Tatyanazaxarova
Урок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен даннымиУрок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен данными
Tatyanazaxarova
Урок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметикаУрок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметика
Tatyanazaxarova
Урок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибокУрок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибок
Tatyanazaxarova
Урок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибокУрок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибок
Tatyanazaxarova
Урок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном кодеУрок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном коде
Tatyanazaxarova
Урок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияУрок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложения
Tatyanazaxarova
Урок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурацииУрок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурации
Tatyanazaxarova
PVS-Studio
PVS-Studio PVS-Studio
PVS-Studio
Tatyanazaxarova
PVS-Studio научился следить за тем, как вы программируете
PVS-Studio научился следить за тем, как вы программируетеPVS-Studio научился следить за тем, как вы программируете
PVS-Studio научился следить за тем, как вы программируете
Tatyanazaxarova
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Tatyanazaxarova
Статический анализ и ROI
Статический анализ и ROIСтатический анализ и ROI
Статический анализ и ROI
Tatyanazaxarova
Вечный вопрос измерения времени
Вечный вопрос измерения времениВечный вопрос измерения времени
Вечный вопрос измерения времени
Tatyanazaxarova
По колено в Си++ г... коде
По колено в Си++ г... кодеПо колено в Си++ г... коде
По колено в Си++ г... коде
Tatyanazaxarova
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Tatyanazaxarova
Урок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окруженияУрок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 27. Особенности создания инсталляторов для 64-битного окружения
Tatyanazaxarova
Урок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программУрок 26. Оптимизация 64-битных программ
Урок 26. Оптимизация 64-битных программ
Tatyanazaxarova
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибокУрок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Tatyanazaxarova
Урок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. ИсключенияУрок 20. Паттерн 12. Исключения
Урок 20. Паттерн 12. Исключения
Tatyanazaxarova
Урок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен даннымиУрок 19. Паттерн 11. Сериализация и обмен данными
Урок 19. Паттерн 11. Сериализация и обмен данными
Tatyanazaxarova
Урок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметикаУрок 17. Паттерн 9. Смешанная арифметика
Урок 17. Паттерн 9. Смешанная арифметика
Tatyanazaxarova
Урок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибокУрок 8. Статический анализ для выявления 64-битных ошибок
Урок 8. Статический анализ для выявления 64-битных ошибок
Tatyanazaxarova
Урок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибокУрок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибок
Tatyanazaxarova
Урок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном кодеУрок 6. Ошибки в 64-битном коде
Урок 6. Ошибки в 64-битном коде
Tatyanazaxarova
Урок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложенияУрок 5. Сборка 64-битного приложения
Урок 5. Сборка 64-битного приложения
Tatyanazaxarova
Урок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурацииУрок 4. Создание 64-битной конфигурации
Урок 4. Создание 64-битной конфигурации
Tatyanazaxarova
PVS-Studio научился следить за тем, как вы программируете
PVS-Studio научился следить за тем, как вы программируетеPVS-Studio научился следить за тем, как вы программируете
PVS-Studio научился следить за тем, как вы программируете
Tatyanazaxarova
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...
Tatyanazaxarova
Статический анализ и ROI
Статический анализ и ROIСтатический анализ и ROI
Статический анализ и ROI
Tatyanazaxarova
Вечный вопрос измерения времени
Вечный вопрос измерения времениВечный вопрос измерения времени
Вечный вопрос измерения времени
Tatyanazaxarova
По колено в Си++ г... коде
По колено в Си++ г... кодеПо колено в Си++ г... коде
По колено в Си++ г... коде
Tatyanazaxarova
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Трепещи, мир! Мы выпустили PVS-Studio 4.00 с бесплатным анализатором общего н...
Tatyanazaxarova

Урок 21. Паттерн 13. Выравнивание данных

  • 1. Урок 21. Паттерн 13. Выравнивание данных Процессоры работают эффективнее, когда имеют дело с правильно выровненными данными. А некоторые процессоры вообще не умеют работать с не выровненными данными. Попытка работать с не выровненными данными на процессорах IA-64 (Itanium), как показано в следующем примере, приведет к возникновению исключения: #pragma pack (1) // Also set by key /Zp in MSVC struct AlignSample { unsigned size; void *pointer; } object; void foo(void *p) { object.pointer = p; // Alignment fault } Если вы вынуждены работать с не выровненными данными на Itanium, то следует явно указать это компилятору. Например, воспользоваться специальным макросом UNALIGNED: #pragma pack (1) // Also set by key /Zp in MSVC struct AlignSample { unsigned size; void *pointer; } object; void foo(void *p) { *(UNALIGNED void *)&object.pointer = p; //Very slow } В этом случае компилятор сгенерирует специальный код, который будет работать с не выровненными данными. Такое решение неэффективно, так как доступ к данным будет происходить в несколько раз медленнее. Если целью является уменьшение размера структуры, то лучшего результата можно достичь, располагая данные в порядке уменьшения их размера. Подробнее об этом будет рассказано в одном из следующих уроков. На архитектуре x64 при обращении к не выровненным данным исключения не возникает, но их также следует избегать. Во-первых, из-за существенного замедления скорости доступа к таким данным, а во-вторых, из-за возможности переноса программы в будущем на платформу IA-64.
  • 2. Рассмотрим еще один пример кода, не учитывающий выравнивание данных: struct MyPointersArray { DWORD m_n; PVOID m_arr[1]; } object; ... malloc( sizeof(DWORD) + 5 * sizeof(PVOID) ); ... Если мы хотим выделить объем памяти, необходимый для хранения объекта типа MyPointersArray, содержащего 5 указателей, то мы должны учесть, что начало массива m_arr будет выровнено по границе 8 байт. Расположение данных в памяти на разных системах (Win32/Win64) показано на рисунке 1. Рисунок 1- Выравнивание данных в памяти на системах Win32 и Win64 Корректный расчет размера должен выглядеть следующим образом: struct MyPointersArray { DWORD m_n; PVOID m_arr[1]; } object; ...
  • 3. malloc( FIELD_OFFSET(struct MyPointersArray, m_arr) + 5 * sizeof(PVOID) ); ... В приведенном коде мы узнаем смещение последнего члена структуры и суммируем это смещение с его размером. Смещение члена структуры или класса можно узнать с использованием макроса offsetof или FIELD_OFFSET. Всегда используйте эти макросы для получения смещения в структуре, не опираясь на знание размеров типов и выравнивания. Пример кода с правильным вычислением адреса члена структуры: struct TFoo { DWORD_PTR whatever; int value; } object; int *valuePtr = (int *)((size_t)(&object) + offsetof(TFoo, value)); // OK Разработчиков Linux-приложений может ждать еще одна неприятность, связанная с выравниванием. О ней вы можете прочитать в нашем блоге в посте "Изменения выравнивания типов и последствия". Диагностика Поскольку работа с не выровненными данными не приводит к ошибке на архитектуре x64, а только к снижению производительности, инструмент PVS-Studio не предупреждает об упакованных структурах. Но если для вас критична производительность приложения, рекомендуем просмотреть все места в программе, где используется "#pragma pack". Для архитектуры IA-64 данная проверка более актуальна, но анализатор PVS-Studio пока не ориентирован на верификацию программ для IA-64. Если вы работаете с системами на базе Itanium и планируете приобрести PVS-Studio, напишите нам, и мы обсудим вопросы адаптации этого инструмента к особенностям IA-64. Инструмент PVS-Studio позволяет обнаружить ошибки, связанные с вычислением размеров объектов и смещений. Анализатор обнаруживает опасные арифметические выражения, содержащие в себе несколько операторов sizeof(), что свидетельствует о возможной ошибке. Диагностическое сообщение имеет номер V119. Однако во многих случаях использование нескольких операторов sizeof() в рамках одного выражения корректно и анализатор игнорирует подобные конструкции. Пример безопасных выражений с несколькими операторами sizeof: int MyArray[] = { 1, 2, 3 }; size_t MyArraySize =
  • 4. sizeof(MyArray) / sizeof(MyArray[0]); //OK assert(sizeof(unsigned) < sizeof(size_t)); //OK size_t strLen = sizeof(String) - sizeof(TCHAR); //OK Приложение На рисунке 2 представлены размеры типов и их выравнивание. Для изучения размеров объектов и их выравнивания на различных платформах вы также можете воспользоваться примером кода, приведенным в записи блога "Изменения выравнивания типов и последствия". Рисунок 2 - Размеры типов и их выравнивание.
  • 5. Авторы курса: Андрей Карпов (karpov@viva64.com), Евгений Рыжков (evg@viva64.com). Правообладателем курса "Уроки разработки 64-битных приложений на языке Си/Си++" является ООО "Системы программной верификации". Компания занимается разработкой программного обеспечения в области анализа исходного кода программ. Сайт компании: http://www.viva64.com. Контактная информация: e-mail: support@viva64.com, 300027, г. Тула, а/я 1800.