LINUX.ORG.RU

Выполнение функций С/C++ на уровне системы


0

0

Здравствуйте, в последнее время начал интересоваться аспектами выполнения программ на уровне системы.

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

Вопросы: Как происходит выполнение функций С++ и функций С на уровне системы в Windows, BSD и Linux системах? Например, я часто вызываю какую - то функцию, ложит ли её система в кэш процессора целиком или подгружает каждый раз? Если в кэш, то как влияет на кэширвоание размер функции (например, хоть он и сферический в вакууме, еси функция больше размеров кэша)? Inline функции в С++ существуют только для компилятора (т.е., их код вставляется в код ввызывающей функции) или же у ОС имеются свои хитрые способы работы с функциями, вызывающими inline функции?

Был бы очень благодарен за более - менее подробное описание или ссылку на хороший ресурс или книжку о работе с функциями.


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

>Эм, ты в курсе, что c++ и c это компилируемые языки? А в gcc еще и в промежуточный код.

Вполне в курсе. А вот вы не совсем поняли, что я пытаюсь узнать. Точнее, совсем не поняли.

Насколько я знаю по самописным процессорам (FPGA - процессоры для DSP), любой скомпиленный код - набор двоичных кодов асмовых. Так вот, в этом коде присутствуют данные для обработки и асмовые команды для процессора. Любая функция С/С++ после компиляции - последовательность асмовых комманд, висящих в оперативке.

Так вот, вопрос был мой таким: что делает операционка с набором асмовых команд являющихся скомпиленными функциями С/С++? Пишет ли она их в кэш проца, если функция в дальнейшем будет вызываться многократно? Как оперирует функциями С и С++ (комплиятроы - то разные совсем, есть ли какие - то особенности компиляции, которые определяют, что должна операционка делать с данным набором асмовых команд [например, уложить их в кэш проца какого - то определённого уровня])?

trimm
() автор топика
Ответ на: комментарий от Love5an

Love5an, вы намекаете, что операционка вообще не имеет отношения к таким вещам? Все решения о кэше принимает непосредственно логика (логика железа) процессора без вмешательства со стороны ОС?

trimm
() автор топика

аспектами выполнения программ на уровне системы.

также выполняются как и в юзерспейсе(ring3 итд)

рекоммендацию хорошей книжки...сведения...

интернете...кусочки, т.к. не вижу картины целиком.

1. плохо ищешь
2. у тебя совсем нет базы. начни с книжек по Си. Сразу в поисковике вбивай Керниган и Ритчи.
3. научись сразу различать С и С++. пока не поработаешь с каждым с полгодика не имеешь права их смешивать и тп.

Как происходит выполнение функций С++ и функций С

на уровне системы в Windows, BSD и Linux системах?

никак они не выполняют ф-й си и с++, там везде машиный код(гуру не вбивайте ему ща в голову комы и конвенции вызовов - он си пока еще невкуривает)

система в кэш процессора целиком...

недумай об этом

Inline функции в С++ существуют только для компилятора

не совсем точно, а посему недумай об этом сейчас

работе с функциями

нет книжек по функциям, но по Си и С++ имеются. где? полный интернет завален ими помимо упомянутого вначале K&R.

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

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

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

Boy_from_Jungle, я бы с радостью конкретизировал ,если бы обладал уже определённым багажом в этой области. Поэтому и просил источники посоветовать. Конечно, была надежда, что прийдёт какой - нить добрый самритянин прийдёт, прочитает мои мысли и всё распишет, но она в пределе была равна нулю.

На данный момент я не знаю механизмов даже в общем виде при работе софта под ОС (до этого писал софт на DSP в основном, а там с ОС напряг, а софт под ОС писал дял фана и в механизмы работы ОС не лез), поэтому, я даже не знаю, как толково спросить, чтолбы меня поняли люди, разбирающиеся в этой области.

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

Конечно, была надежда, что прийдёт какой - нить добрый

самритянин прийдёт, прочитает мои мысли и всё распишет,

но она в пределе была равна нулю.

все поняли что тебе надо. проблема в том что ты непоймешь ответа

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

все поняли что тебе надо. проблема в том что ты непоймешь ответа

Это точно

2trimm в твоём вопросе много ньюансов, литературы хватает, так что читай понемногу.

Boy_from_Jungle ★★★★
()

1) ОС грузит программу в память и передает управление путем установки нужного значения PC (Program Counter)

2) Как работать с памятью — решает сам процессор. Кэшированием тоже занимается сам процессор. ОС и компилятор помогают ему, выравнивая страницы памяти и данные в памяти.

3) Читать http://people.redhat.com/drepper/cpumemory.pdf до просветления

4) http://ru.wikipedia.org/wiki/Гарвардская_архитектура и http://ru.wikipedia.org/wiki/Архитектура_фон_Неймана

5) http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

Как происходит выполнение функций С++ и функций С на уровне системы в Windows, BSD и Linux системах?

Формируется запись об активации функции (== stack frame), вычисляется адрес начала кода функции, происходит переход по этому адресу.

Inline функции в С++ существуют только для компилятора (т.е., их код вставляется в код ввызывающей функции) или же у ОС имеются свои хитрые способы работы с функциями, вызывающими inline функции?

Существуют только для компилятора. Компилятор тогда вставляет не код вызова функции, а само тело функции.

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

> На данный момент я не знаю механизмов даже в общем виде при работе софта под ОС (до этого писал софт на DSP в основном, а там с ОС напряг, а софт под ОС писал дял фана и в механизмы работы ОС не лез), поэтому, я даже не знаю, как толково спросить, чтолбы меня поняли люди, разбирающиеся в этой области.

Процессор не особо разбирается в языках программирования, поэтому он пихает в кеш всё, что попадёт под руку(*). Кеша для всего не хватает, поэтому некоторые данные из него приходится вытеснять. Логично вытеснять наименее используемые данные, что процессор и делает.

* Процессоры часто имеют специальные инструкции, тем или иным образом управляющие кешем: сброс строки, загрузка или выгрузка данных, минуя кеш. Принятие решения по использованию этих команд остаётся за человеком, т.к. компиляторы ещё не на столько умны.

mv ★★★★★
()

Может стоит немного познакомится с ассемблером? Тогда подобные вопросы станут ясны как свет фар встречного автомобиля.

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

Знаком, но не с х86, а с самописным, в АЛУ которого добавлял элементы, остальные эелементы были реализованы не мной, посему, как они действовали я ума не приложу.

В тех процессорах принцип был схож с тем, что описан mv, только кеш заполнялся циклически с вытеснением самых старых данных и была специальная команда, которая блокировала дял перезаписи определёныый массив памяти.

trimm
() автор топика

Итак, чтобы подвести итог, для всех, у кого возникнет подобный вопрос в будущем:

Более - менее детальный овтет дан в следующих постах: http://www.linux.org.ru/view-message.jsp?msgid=4275052&lastmod=1259230795853#... http://www.linux.org.ru/view-message.jsp?msgid=4275052&lastmod=1259230795853#...

Рекомендованная литература указана в посте: http://www.linux.org.ru/view-message.jsp?msgid=4275052&lastmod=1259230795853#...

Также, для ознакомления рекоммендованы: Керниган Б., Ритчи Д. Язык программирования Си Мануал по процессорам интел, в частности: http://www.intel.com/products/processor/manuals/

Спасибо всем за советы и внимание.

Если у кого появятся дополнительные комментарии или ссылки, не стесняйтесь их добавлять.

trimm
() автор топика

Например, я часто вызываю какую - то функцию, ложит ли её система в кэш процессора целиком или подгружает каждый раз?

Система обычно не имеет отношения к кешу, процессор сам им управляет. Да, эта функция будет в кеше, по крайней мере её отдельные куски, которые сейчас выполняются.

Если в кэш, то как влияет на кэширвоание размер функции (например, хоть он и сферический в вакууме, еси функция больше размеров кэша)?

Будет лежать кусок, который используется в данный момент.

Inline функции в С++ существуют только для компилятора (т.е., их код вставляется в код ввызывающей функции) или же у ОС имеются свои хитрые способы работы с функциями, вызывающими inline функции?

inline - это программист считает, что эту функцию неплохо бы заинлайнить в места её вызова. Реально произойдёт то, что думает конкретный компилятор (а он может иметь на эти вещи свою точку зрения).

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

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

http://rus-linux.net/lib.php?name=/MyLDP/hard/memory/memory.html

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

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

Да, mv все прояснил, но я просто имел ввиду что изучение ассемблера дает представление о том что реально представляет собой бинарник и как он исполняется в процессоре. Правда кеш сюда не входит, и для любого (asm, C) программиста он прозрачен, но при изучении ассемблера рано или поздно все равно с назначением и принципом работы кеш-памяти придется пересечься.

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

>Насколько я понимаю, операционка ничего не делает со скомпилированным кодом функций. Они выполняются процессором и он сам решает, что и сколько храниться в кеше.
Совершенно верно. ОС просто настраивает указатель на поток команд (программу) А и процессор их по очереди исполняет, потом ОС просыпается (через прерывание таймера) и меняет указатель на поток команд Б, так начинает выполнятся следующая программа. Для ОС кеша процессора не существует.

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

Спасибо за ссылку. Очень интересно.

trimm
() автор топика
Ответ на: комментарий от urxvt

УГу. В моём софте этим занимался специальный планировщик, вместо ОС.

Если в общем, то меня смущала именно ОС. Я думал, что она даёт дополнительные пункты взаимодействия с процессором, не определяемые кодом самой программы (например, управление кэшированием).

Правда, мне не совсем понятно, почему никто не встраивал в ОС возможности блокирования кэша на перезапись (при наличии такой возможности у процессора). Ведь логично, что ОС может перед запуском статистическими методами определить наиболее часто вызываемые функции данной программы и поместить их в блокированный на перезапись участок кэш - памяти. ПРавда, опять же, здесь могут быть ещё какие - то подводные камни для ОСестроителей, о которых я просто не имею понятия.

Буду читать материалы, которые здесь предложили, а информации там куча. Да и разбираться в ОС и её работе. Хоть и не надо оно мне по специфике работы, но крайне интересно, но ничего особо пока не понятно. Хотя, похоже, многие механизмы будут сходны с тем, что делал сам. Не по реализацции, что естественно, а по логике.

Legioner, Liosha_Syrnikov, спасибо за дополнение и ответы.

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

> перед запуском статистическими методами определить наиболее часто вызываемые функции данной программы

Это как?

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

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

Что-то совсем утопическое получается :)

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

При первом исполнении. Еси потом сохранить, какие участки кода держать, то второй запуск буит быстрее. Хотя. Я хз. Ладно. Больше не буду выставлять свою неграмотность. Пойду читать материалы.

trimm
() автор топика
Ответ на: комментарий от pained

> который по мере использования программы

Читаем внимательно! Ключевые слова «перед запуском» и «статистически». Меня именно это интересует.

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

LamerOk, ну дык в двух же постах описана идея (не исключаю, что пишу смешные вещи, но, как по мне, исходя из знаний того, что выполнял сам, реализуемо). Сделать холодный старт программы и собрать статистистику на тему того, на какие участки памяти чаще осуществляецца переход, насколько часто, длительность исполнения кода до перехода на следующий участок. НА основе этого можно построить в первом приближении оптимальную карту подгрузок кода в кэш и блокирования определённой части кэше на перезапись). Карту сохранить на винт. Когда подгружаецца несколько программ с такими картами, то кэш заполняецца по приоритету, плюс, обязательно должно быть достаточно свободного места в кэше неблокированного. Т.е., здесь уже расчитываецца не локальный, а глобальный оптимум. Правда, учитывая количество служб, которые постоянно висят в ОС, целесообразность такой подсистемы под вопросом из - за небольшого кэша современных процессоров, да и глобальный оптимум и карту подгрузок тяжело буит с точки зрения вычислений рассчитать.

anarquista, безумно платфоромозависимо. ТАкое чувство, что сейчас всё абсолютно платформонезависимо, не?

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

> холодный старт программы

Прикладной под ОС? И это не «перед», это - сильно после. Старт то уже произошел.

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

Старт приложения. )))

В обычном мире, если речь идет о оптимизации приложения _до запуска_, имеется в виду оптимизация при сборке и так далее. До действительного запуска программы на счет.

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

Есть же gcc с -fprofile-generate/-fprofile-use. Оптимизация происходит не без запуска, но при последующей сборке на основе статистики собранной при выполнении.

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

Эта статистика очень сильно запрыгает в зависимости от поданных на вход данных, так что на практике эту фичу никто не использует.

LamerOk ★★★★★
()

мне понравились 2 идеи:

1. дать ОС возможность приоритезировать кэш (совсем залочить че-то в кэше вряд ли полезно)

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

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

1. Совсем залочить я имел в виду для локального случая, когда имеет место выполнение одного единственного приложения. Для ОС - именно приоретизация. Меня, как обычно, подвело отсутствие грамотного владения разговорным языком.

Если это всё реализуемо на самом деле, то почему этого никто до сих пор не сделал - вот вопрос. Может, есть какие - то камни подводные о которых я в силу своей некомпетентности просто не знаю.

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

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

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

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

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

Да и так ведь читаем если надо - oprofile

gena2x ★★★
()

отвечу своим вариантом:

Как происходит выполнение функций С++ и функций С на уровне системы в Windows, BSD и Linux системах?

Из функции делается символ, кладётся либо в исполняемый файл либо в либу - кусок бинарного кода с описанием. Ос загружает бинарник и все функции из нужных библиотек. После этого говорит процессору выполнять начиная например с того адреса куда загрузился main. Читать что-нить общее по построению ОС, например таненбаума. Когда исполнение доходит до определённой части кода, то он засасывает тот кусок памяти где хранится код в кэш (это делается превентивно, за исключением ветвлений), освободая кэш от старых данных. Засосав, процессор спокойно получает из кэша инструкции. Получается что если цикл например достаточно мал - работает из кеша. Что и каким конкретно образом загружается описано в тн ABI для платформы. читать - elf, ABI.

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