Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 13.09.2015
Сообщений: 16

Оптимизация кода, нарушающего правила strict aliasing

13.09.2015, 10:57. Показов 2205. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Имеется такой код в ядре Linux:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* include/linux/netlink.h */
....
#define NETLINK_CB(skb)         (*(struct netlink_skb_parms*)&((skb)->cb))
....
/**
 * nlmsg_multicast - multicast a netlink message
 * @sk: netlink socket to spread messages to
 * @skb: netlink message as socket buffer
 * @pid: own netlink pid to avoid sending to yourself
 * @group: multicast group id
 * @flags: allocation flags
 */
static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
                                  u32 pid, unsigned int group, gfp_t flags)
{
        int err;
 
        NETLINK_CB(skb).dst_group = group;
 
        err = netlink_broadcast(sk, skb, pid, group, flags);
        if (err > 0)
                err = 0;
 
        return err;
}
стоит задача оптимизации этого кода так, чтобы он не нарушал правила strict aliasing ( http://cellperformance.beyond3... asing.html ). Да, я знаю, у линукса другая политика относительно правил strict aliasing и по умолчанию ядро компилируется с -fno-strict-aliasing, но все же интересно, можно ли сколько-нибудь заметно оптимизировать работу ядра, путем приведения таких примеров кода, к аналогичным, не нарушающим strict aliasing.
После некоторого раздумья я пришел к такому варианту:
C
1
2
3
4
5
6
7
static struct netlink_skb_parms *to_netlink_skb_parms(struct sk_buff *skb) {
       struct netlink_skb_parms *tmp;
       memcpy(&tmp, &((skb)->cb), 48);
       return tmp;
}
 
#define NETLINK_CB(skb) to_netlink_skb_parms(skb)
На что компилятор ответил:
C
1
2
3
4
In file included from /media/chrono/Other/Chrono_Kernel-1/lib/kobject_uevent.c:25:0:
/media/chrono/Other/Chrono_Kernel-1/include/linux/netlink.h: In function ‘nlmsg_multicast’:
/media/chrono/Other/Chrono_Kernel-1/include/linux/netlink.h:38:24: error: request for member ‘dst_group’ in something not a structure or union
         NETLINK_CB(skb).dst_group = group;
В чем ошибка? Для полноты картины привожу также определения структур struct netlink_skb_parms и sk_buff :
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct netlink_skb_parms {
    struct ucred        creds;      /* Skb credentials  */
    __u32           pid;
    __u32           dst_group;
};
 
struct sk_buff {
    .....
 
    /*
     * This is the control buffer. It is free to use for every
     * layer. Please put your private variables there. If you
     * want to keep them across layers you have to do a skb_clone()
     * first. This is owned by whoever has the skb queued ATM.
     */
    char            cb[48] __aligned(8);
 
    ....
};
Попутный вопрос. Написал простейший бенчмарк для сравнения производительности кода с нарушением strict aliasing и без(используя аналогичный исходному код). https://github.com/ChronoMonochrome/C_tests
Судя по получившимся результатам, в случае нарушений strict aliasing, код работает примерно на 20% медленнее. Другое дело, что применения флага -fstrict-aliasing, похоже, вообще не повлияло на скорость работы кода. Вопрос в следующем - означает ли это, что применение -fstrict-aliasing само по себе не оптимизирует код, а лишь позволяет выявлять (вкупе с -Wstrict-aliasing) то, что файл нарушает strict aliasing?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.09.2015, 10:57
Ответы с готовыми решениями:

warning: dereferencing pointer 't' does break strict-aliasing rules
Здравствуйте, уважаемые специалисты! К чему может привести данное предупреждение? Что нужно сделать, чтобы его не было? typedef...

Strict aliasing и memcpy
Что-то я никак не врублюсь, как согласуются между собой strict aliasing и функции жонглирующие void*? Возьмем для примера memcpy....

Каламбур типизации и strict aliasing
Есть ли какой-то стандартный способ обойти strict aliasing, с гарантией от UB? Конкретная задача: дан массив чисел. Требуется отсортировать...

5
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
13.09.2015, 11:43
Лучший ответ Сообщение было отмечено Radical_Dreamer как решение

Решение

Цитата Сообщение от Radical_Dreamer Посмотреть сообщение
стоит задача оптимизации этого кода так, чтобы он не нарушал правила strict aliasing
Это не оптимизация, а пессимизация. Люди повсеместно нарушают strict aliasing из-за того, что с нарушениями в общем случае текст программы становится короче и понятнее, а код быстрее. Чтобы писать код без нарушений, надо повсеместно разводить возню с memcpy (что для Си++ вообще является непацанским действием). Да в общем-то и по твоей ссылке с бенчмарком присутствует именно это. Конкретно компилятор gcc умеет превращать memcpy во встроенный код копирования, а потом его вычистить от мусора. Умеют ли другие компиляторы - это вопрос

Цитата Сообщение от Radical_Dreamer Посмотреть сообщение
Судя по получившимся результатам, в случае нарушений strict aliasing, код работает примерно на 20% медленнее
Ты не то выбрал в качестве причины. Реальной причиной замедления (или ускорения) кода является опция -fstrict-aliasing (которая включена по умолчанию). По этой опции включаются дополнительные оптимизации, которые позволяют более эффективно построить код за счёт перестановки местами операций load и store (примерная идея описана под спойлером тут: [Задача] Адресная арифметика). Эта опция закладывается на то, что в программе нет нарушений strict aliasing'а, а потому перестановки load'ом начинают применяться там, где компилятор не может аналитически доказать, что две операции обращения в память являются не зависимыми и считает их независимыми на основании языковых типов, в предположении, что согласно strict aliasing'у обращения в память для разных типов независимы

Добавлено через 2 минуты
Цитата Сообщение от Radical_Dreamer Посмотреть сообщение
Вопрос в следующем - означает ли это, что применение -fstrict-aliasing само по себе не оптимизирует код, а лишь позволяет выявлять (вкупе с -Wstrict-aliasing) то, что файл нарушает strict aliasing?
Не правильно. Применение -fstrict-aliasing позволяет лучше оптимизировать программы, написанные без нарушения strict aliasing'а. В своё время проводили замеры, эффект порядка 1% и меньше. А потому народ повсеместно плюёт на strict aliasing. В gnu'шном софте в большом количестве программ используется опция -fno-strict-aliasing, потому что люди не хотят заниматься онанизмом
5
0 / 0 / 0
Регистрация: 13.09.2015
Сообщений: 16
13.09.2015, 12:42  [ТС]
Evg, спасибо за подробный и развернутый ответ. Просто встречал пример на хабре, который вроде бы как после оптимизации заработал в 1.5 раза быстрее(хотя лично мне не удалось получить какой-либо разницы), а также замены преобразования типов на memcpy на gerrit'е cyanogenmod'а, я уж было подумал, что эта оптимизация чего-либо стоит. А так получается, в "лучшем" случае отгенерирует какой-нибудь некорректный код ценой ускорения, которого даже замерить трудно. Еще раз прогнал бенчмарк, но с -O3, и теперь во всех случаях получился примерно одинаковый результат. Полагаю, вопрос закрыт, и тему можно закрыть.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
13.09.2015, 13:21
Цитата Сообщение от Radical_Dreamer Посмотреть сообщение
А так получается, в "лучшем" случае отгенерирует какой-нибудь некорректный код ценой ускорения, которого даже замерить трудно
Некорректный код сгенерируется только в том случае, если исходник был некорректный. По факту имеем, что огромное количество исходников являются некорректными (с точки зрения 100% соответствия стандарту). В случае strict aliasing'а мы имеем дело со случаем, когда реальная жизнь оказывается таковой, что люди не хотят соблюдать стандарт в этом месте, потому что здравый смысл в этом месте преобладал над стандартом. Это не общее правило, а единичное исключение

Насчёт ускорения - множество оптимизаций выглядят примерно так же: каждая даёт привар по чуть-чуть. Но оптимизаций много, и в сумме они дают хороший привар. Для каждой оптимизации есть специфичная область применения и на каждую оптимизацию можно написать синтетический код, который даст весьма ощутимое ускорение. Сама оптимизация отдельно взятая может вообще не иметь никакого эффекта, но имеет сильный эффект для оптимизаций, работающих после неё. Так что тут всё слишком сложно. Конкретно strict aliasing конкретно на интеле большого привара не даёт, т.к. на интеле аппаратура в этом месте хорошо работает, а кэша много. Для других процессоров эффект от strict aliasing'а вполне может оказаться намного большим, чем 1%
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
22.06.2016, 14:52
До кучи сюда подкину ссылок, чтобы всё было в одной теме

Часто требуется сделать "битовое копирование". Типа того, что из переменной float32 получить битовый образ в переменную int32. Есть разные способы, но не все они формально корректны с точки зрения strict aliasing rules: Битовый формат согласно спецификации IEEE 745

В одной из тем, посвящённой union'ам, присутствует выдержка из стандарта:
Union что из себя представляет?
Union что из себя представляет?
Вкратце с точки зрения стандарта суть сводится к тому, что одновременно читать-писать можно только в одно из полей union'а

Добавлено через 4 часа 40 минут
Вот ещё хорошая ссылка по теме https://habrahabr.ru/post/114117/
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.04.2017, 09:51
Тип float нельзя сдвигать?

Для Си и Си++ в этом месте разное поведение стандарта
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.04.2017, 09:51
Помогаю со студенческими работами здесь

Union, new placement, strict-aliasing, cross-platform
Доброго времени суток. Ниже представленный код вроде бы работает. Гонял его на компиляторах cl/mingw ...

Оптимизация кода и правила хорошего тона
Доброе утро! Изучаю php и сразу пытаюсь делать все грамотно и не плодить лишнего. Так вот подскажите как можно упростить мой код и какие...

Реализовать 2 статических анализатора исходного кода, которые будут проверять правила оформления кода
Доброго времени суток. Уже читал подобную пост здесь "Парсер С++", но немного не то. Задача: реализовать 2 статических анализатора...

Оптимизация методом Ньютона (нахождение точки минимума). Оптимизация кода
MATLAB только начал осваивать. Попытался реализовать нахождение точки минимума методом Ньютона для функции 2*X12 - X1*X2 + 3*X22 -...

Оптимизация кода. Замер времени выполнения части кода.
Доброе утро. Есть желание посмотреть сколько времени занимает выполнение какого-то блока кода/отдельной функции или процедуры/программы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru