LINUX.ORG.RU

Применение специальных возможностей GCC в ядре Linux

 ,


0

0

В ядре Linux® используется ряд особых возможностей набора компиляторов GNU (GCC) — от возможностей упрощения и более короткой записи до предоставления компилятору подсказок для оптимизации кода. Откройте для себя некоторые из этих особых возможностей GCC и узнайте, как их использовать в ядре Linux.

>>> Подробности

★★★

Проверено: Shaman007 ()

Ответ на: комментарий от Manhunt

> Ну давай, расставь this.

А вот теперь ты дал интересный пример, наводящий на филосовские размышленя... схожу в магазин и запощщу.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> Только работа тут минимальна, обычно хватает расставить this->

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

Manhunt ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> А вот теперь ты дал интересный пример, наводящий на филосовские размышленя...

Это сильно-сильно упрощенный аналог того, что было в продакшене. И нам нужно было не философствовать, а поддерживать код в работоспособном состоянии, и расширять время ото времени. Кефира купи :)

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

> И нам нужно было не философствовать, а поддерживать код в работоспособном состоянии, и расширять время ото времени.

Филосовствовать можно и нужно сейчас. Тем более, речь шла о стандарте как способе избежать этого.

Понятно, что практически в таком случае я бы написал скрипт, и на твой пример хватило бы 10 строк, но это -- кривой костыль. Что же не костыль?

Стандарт я думаю тебе бы не помог, т.к. любой язык расширяется, и СТАНДАРТ НЕСОВМЕСТИМО МЕНЯЕТСЯ СО ВРЕМЕНЕМ. Поправь меня, но тот скачок в g++ 3.4 был не прихотью разрабов и не отказом от красивого ж++-расширения, а следованием изменившемуся станадрту.

Попытки держать полную совместимость между версиями стандарта либо отбрасывают, как невозможные, либо ведут к утяжелению и так слишком тяжолого синтаксиса плюсов.

Решением была бы *нормальная форма* + утилита преобразования участков исходников в нормальную форму.

Т.е. для каждой сокращенной синтаксической конструкции должна существовать нормальная форма. Например, в случае

template<class T> class B<T>: public A<T> { typedef t1 t2; };

(не полностью развернутой) нормальной формой могла бы быть

template<class T> class::B<T>: public class::A<T> { typedef typename::A<T>::t1 typename::A<T>::t2; };

дальше -- из нормальной формы можно было бы легко сделать новую версию программы -- либо довольно тупым регулярным выражением, либо, как совсем у нормальных людей, утилитой, идущей к новой версии компилятора.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

очевидный фикс:

template<class T> class::B<T>: public class::A<T> { typedef typename::A<T>::t1 typename::B<T>::t2; };

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Еще один плюс нормальной формы -- с ее помощью можно было бы проверять, что программа, уменьшенная (для лучшей читабельности) регулярным выражением, осталась по значению той же самой.

Т.е. можно не боясь багов гонять свои довольно простые (=тупые) скрипты при переходе к новой версии компилятора.

Я не уверен, что выхлоп ж++ (gimple и прочие) дают сейчас такую возможность.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от yantux

>> какая из рюшечек по-твоему из ООП?

> Опс, сори. Виноват, не помню. Но в коде ядрая явно имеет место ООП подход на Си. Почему разработчики ядра не используют с++?

По багам в голове т. Торвальдса (или их отсутствию) я не специалист. Вроде как причины есть. Вроде как профит от автоматизации из плюсов весьма мал, vtable плюсовый они использовать не будут, исключения плюсовые могут только подгадить -- так что...

Наиболее ценные рюшки -- не ООП, а функциональные и низкоуровневые (и не требуют асма).

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Manhunt

>  и расширять время ото времени.

g++ сопротивляется моим попыткам хоть как-то приблизиться
к нормальной форме без нарушения стандарта:

template<typename T> struct A { 
    typedef int X; 
};
template<typename T> struct B: public A<T> { 
    typedef typename::A<T>::X ::B::Y; // error: declaration does not declare anything
};

int main()
{
    A<int> a;
    B<int> b;
    return 0;
}



www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> Стандарт я думаю тебе бы не помог, т.к. любой язык расширяется, и СТАНДАРТ НЕСОВМЕСТИМО МЕНЯЕТСЯ СО ВРЕМЕНЕМ. Поправь меня, но тот скачок в g++ 3.4 был не прихотью разрабов и не отказом от красивого ж++-расширения, а следованием изменившемуся станадрту.

Не прав. Стандарт на плюсы пока только один: iso/iec 14882. Версии 14882:1998 и 14882:2003 отличаются лишь мелкими уточнениями, можешь посмотреть: http://www.acceleratedcpp.com/authors/koenig/c++std/revisions.pdf

Новый стандарт c++0x, который вот-вот примут, обладает практически полной обратной совместимостью. А скачек был связан с тем, что gcc наконец-то приблизили к стандарту.

Даже если разные версии стандартов не полностью совместимы, это обязано лечиться опциями в духе -ansi, -std=c89, -std=iso9899:1990.

> Попытки держать полную совместимость между версиями стандарта либо отбрасывают, как невозможные, либо ведут к утяжелению и так слишком тяжолого синтаксиса плюсов.


Если ты посмотрешь на исторические факты, то обнаружишь, что в c и в c++ обратную совместимость держат практически стопроцентную. Для тех, кто не полагался на то, чего стандарт не обещает.

> template<class T> class::B<T>: public class::A<T> { typedef typename::A<T>::t1 typename::A<T>::t2; };


Сразу видно, что ты практически не пишешь шаблонного кода. Процитированная строчка - откровенно бредовая (ты, находясь в теле класса B<T>, пытаешься запихнуть t2 в пространтво имен класса A<T>). Не говоря уже об убитом синтаксисе.

> Т.е. для каждой сокращенной синтаксической конструкции должна существовать нормальная форма.


А теперь представь, что мне понадобилось поменять родителя с A на AA. С твоей "нормальной формой" (ты сам ее такую придумал?) придется перепахать весь класс B, меняя упоминания A на AA. А если класс A упоминался не только в качестве родителя (и стало быть, в этих упоминания менять A на AA не нужно), то переделка превратится в кошмар. В общем, так, как ты предлагаешь, в здравом уме никто делать не будет. Наоборот, вводят новые имена в своем пространтсве имен, и дальше об их просихождении не впоминают. В духе

template<class T> struct B : public A<T> { typedef A<T> Parent; typedef typename Parent::t1 t2; };

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

> Процитированная строчка - откровенно бредовая (ты, находясь в теле класса B<T>, пытаешься запихнуть t2 в пространтво имен класса A<T>).

я поправился насчет А в следующем своем посте, да и догадаться можно было

> Не говоря уже об убитом синтаксисе.

Он и не предполагался быть настоящим плюсовым. Так, что-то похожее. На самом деле полностью раскрытая нормальная форма может выглядеть намного монструознее.

Но ты за деревьями не увидел леса:

> С твоей "нормальной формой" (ты сам ее такую придумал?) придется перепахать весь класс B, меняя упоминания A на AA.

нормальная форма НЕ предназначена для переписывания руками. Программисты как и раньше будут писать на обычном плюсовом синтаксисе. Нормальная форма будет генериться только тогда, когда есть необходимость перейти на несовместимый диалект, как в случае с 3.4

> С твоей "нормальной формой" (ты сам ее такую придумал?) да, сам. Если тебе это не интересно, я закрою тему нормальной формы. Мне от тебя вполне достаточно примера, наводящего на филосовские размышления.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> На самом деле полностью раскрытая нормальная форма может выглядеть намного монструознее.
> Программисты как и раньше будут писать на обычном плюсовом синтаксисе. Нормальная форма будет генериться только тогда, когда есть необходимость перейти на несовместимый диалект, как в случае с 3.4


То есть ты предлагаешь написать набор скриптов, который из любого диалекта и из любых нестандартных расширений будет рожать соответствующий стандарту (но нечитабельный) код, который можно будет скормить современному компилятору? Муахахаха - удачи в написании парсеров C++. Удачи в отладке сконвертированного кода. Удачи в осознании семантики не поддерживаемого создателями и толком не задокументированного диалекта.

А я по-прежнему предлагаю держаться от нестандартностей как можно дальше.

Manhunt ★★★★★
()

Лучше бы вместо статьи о расширениях написали статью о неочевидных нюансах Си. Таких, как integer promotion + temporaries, strict aliasing, sequence points, signed overflow, и тп. Когда гарантии языка отличаются от наивно-интуитивно-ожидаемого.

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

>Сами ничего толком не умеете, и от того вам нравится разговаривать с другими в снисходительном тоне?

>Обычно бряцанье регалиями начинается там, где заканчиваются аргументы.

Какие аргументы стоит приводить здесь? Для них придется книжки писать. А тот кто в теме итак поймет. Вы знаете что на элементарный вопрос о порядке в которором кладутся аргументы в стек при вызове C функции отвечает сразу в лучшем случае один из 20 кандидатов, про ответ что напечатает printf в след примере я вообще молчу. (многие не уверены в том что это компилируется)
int a = 5;
printf("!ok\n" + (a & 2 && 1));

Про typeof("какой мой тип?") только пятая часть респондентов отвечает. Зато блин каждый третий везде лепит чтo-то вроде:
...
unsigned i;
int min;
...
while(--i > min && max) {
...
}

Потомучто где-то услышал что в C++ оператор прединкримента/прединкримента быстрее работает, а трех грубых ошибок своем коде не найдет...

> BTW по этой причине твой хоумпейдж производит тошнотворное впечатление.


:) это просто записная книжка, польщен что назвали ее домашней страничкой... и вообще потрудились поискать...

>> Видимо это не дает право давать советы учить матчавсть :(

>Не дает права бредить в поучительных тонах.

По крайней мере я только выражаю свое IMHO и аргументирую, а не перехожу на личности.

alexr
()
Ответ на: комментарий от Manhunt

> Лучше бы вместо статьи о расширениях написали статью о неочевидных нюансах Си. Таких, как integer promotion + temporaries, strict aliasing, sequence points, signed overflow, и тп. Когда гарантии языка отличаются от наивно-интуитивно-ожидаемого.

IBM пишет научно рекламные статьи для зеленых программистов и ожидать от них большего похоже пустая трата времени.

Быть может стоит написать самим (только непонятно для какого уважаемого ресурса). Я бы с удовольствием написал например:
*о техниках оптимизации C кода для разных платформ
*о портировании кода для разных платформ.
*GCC assembler constraints, Function/Variable Attributes
*о кэшах
*об алгоритмической оптимизации
*о построении и анализе протоколов, ABI
*о построении и анализе эффективности API
*об особенностях OS и их использовании в высокопроизводительных I/O системах.

alexr
()
Ответ на: комментарий от Manhunt

>В реальности я имел многомегабайтный плюсовый проект. Одним из ключевых кусков которого была сотня килобайт сложного шаблонного кода, и код этот полагался на нестандартное поведение при наследовании. Поведение, которое демонстрировали gcc и msvc тех времен. Аффтары кода, видимо, считали, что знают "что можно, а что нельзя". Прямо как www_linux_org_ru. А потом новые версии gcc привели в соответствие со стандартом, и код тупо перестал собираться. Простыми правками это не лечилось, код нуждался в переписывании. Ни времени, ни ресурсов на которое не было. В итоге мы больше года сидели на старом gcc (пока все же не улучили момент для переделки). И все это время мы не могли использовать появившиеся в новых версиях средства отладки -- а были бы очень к стати. Такова цена использования нестандартных фич

Сочуствую. "Аффтары" не угадали, а тебе расхлебывать...
Но врядли все случилось внезапно, обычно GCC team как минимум год такие фичи держит deprecated. Убрать быстро могли только если были серьезные баги в имплементации.

С другой стороны и развитие стандарта не всегда дружелюбно по отношению к написанному коду, ничего не поделаешь эволюция и "Бритва Оккама" :)

Тут возможно главное точно предсказать в какую сторону стандарт повернет. IMHO время показывает что GCC сейчас это полигон для стандарта :).

alexr
()
Ответ на: комментарий от yantux

>Опс, сори. Виноват, не помню. Но в коде ядрая явно имеет место ООП подход на Си. Почему разработчики ядра не используют с++?

Первая причина в том что большой плюсовый проект очень труден в maintance. По коду совершенно непонятно что на самом деле происходит.
Если часть кода генерится автоматически то это превращается в ночной кошмар. Мой любимый пример это OpenH323 проще выкинуть всю либу чем написать на ее основе что-нибудь нестандартное.

Вторая причина в том что компилятор слишком многое делает неявно. Не хотелось бы напороться на это внутри обработчика page fault :)

Третья причина в большом разнообразии и нестабильности плюсового ABI, runtime и библиотеки совершенно непригодны для пространства ядра, с различными ограничениями на типы памяти и ресурсы в одном и томже коде но в разных режимах.

Четвертая причина в плюсовом подходе наследования и написания кода. Любая архитектурная ошибка посередине может повлечь весьма объемный рефакторинг в монолитном ядре. Любая дополнительная связь низа с верхом, неизбежная в монолитном ядре, к архитектурной катострофе.

Пятая причина в том что C++ слишком строг в преобразовании типов :), что порою усложняет его системнозависимое использование.

Получается что ООП C++ style (с наследованием, потоками, операторами и exceptions) требует сначала много думать потом все равно много исправлять. В C style ООП можно меньше думать о side эффектах и архитектурное несовершенство исправлять крохотными патчами.

В общем IMHO монолитное ядро это не та задача где место C++. Подтверждено временем.

alexr
()
Ответ на: комментарий от alexr

> Быть может стоит написать самим

Хех, у меня не хватит энтузиазма. _Качественную_ статью на эту тему сделать довольно трудно. Написать внятный и легкочитаемый текст, аккуратно сверить со стандартом, подобрать примеры где оно срабатывает в реальной жизни, найти согласных отревьюить экспертов, учесть их замечания. Эксперты после ревью назовут еще охапку интересных моментов, нужно будет вписать и их. И снова сверка, примеры, ревью. Возни много, а мотивации особой нет... Писать абы-как, лишь бы написать, тем более желания нет.

> о кэшах

Кстати, есть весьма хорошая статья про кэши и память. Вот линк: http://people.redhat.com/drepper/cpumemory.pdf

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

>Кстати, есть весьма хорошая статья про кэши и память. Вот линк: http://people.redhat.com/drepper/cpumemory.pdf

Статья хорошая в смысле что достаточно подробно в одном месте описывает то что происходит на x86 и немного на ia64 архитектуре. Но для RISC процессоров есть что добавить. Например:
*использование команд управления кэшами
*более подробно описать методы оптимизации использования L1d и L1i на различных задачах.
*более подробно раскрыть аспект различия virtualy indexed и physicaly indexed кэшей. Какие ограничения и side эффекты(например cache aliasing) могут возникнуть.
*архитектурно зависимые расширения кэшей.
*проблеммы когерентности кэшей и как они решаются.
*синхранизационные барьеры спекулятивного исполнения и доступа к данным.
*описать механизмы достижения атомарности без блокировки шины.

alexr
()
Ответ на: комментарий от alexr

> есть что добавить

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

Больше пользы было бы от грамотного перевода той статьи на русский. Но даже на это себя фиг сподвигнешь.

Manhunt ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.