Где находится исходный код «холодных» функций в glibc?

У меня есть программа hello world на C:

#include <stdio.h>

int main() {
    printf("Hello world!\n");
    return 0;
}

Скомпилируй gcc -static hello.c -o hello

В readelf -a --wide hello я нашел некоторые функции с постфиксом холодный

__assert_fail_base.cold
_nl_load_domain.cold
_IO_new_fclose.cold
_IO_fflush.cold
_IO_puts.cold
_IO_wfile_underflow.cold
_IO_new_file_underflow.cold
_IO_fputs.cold
_IO_fwrite.cold
_IO_getdelim.cold
__printf_fp_l.cold
__printf_fphex.cold
read_encoded_value_with_base.cold
base_of_encoded_value.cold
execute_cfa_program.cold
uw_frame_state_for.cold
uw_install_context_1.cold
execute_stack_op.cold
uw_update_context_1.cold
uw_init_context_1.cold
uw_update_context.cold
_Unwind_RaiseException_Phase2.cold
_Unwind_GetGR.cold
_Unwind_SetGR.cold
_Unwind_Resume.cold
_Unwind_Resume_or_Rethrow.cold
size_of_encoded_value.cold
base_from_object.cold
base_from_cb_data.cold
read_encoded_value_with_base.cold
_Unwind_IteratePhdrCallback.cold
search_object.cold
base_of_encoded_value.cold
read_encoded_value_with_base.cold

Из здесь:

The cold attribute on functions is used to inform the compiler that the function is unlikely to be executed. The function is optimized for size rather than speed and on many targets it is placed into a special subsection of the text section so all cold functions appear close together, improving code locality of non-cold parts of program. The paths leading to calls of cold functions within code are marked as unlikely by the branch prediction mechanism. It is thus useful to mark functions used to handle unlikely conditions, such as perror, as cold to improve optimization of hot functions that do call marked functions in rare occasions.

When profile feedback is available, via -fprofile-use, cold functions are automatically detected and this attribute is ignored.

Соответственно, я скачать glibc и переключаюсь на коммит 160f6c36a374841ee6e2bf2ee0ba05b70634978e, что указывает на мою версию git rev-list -n 1 $(git tag | grep 2.31-0ubuntu9.7), но после всех этих действий я не могу найти ни одной функции сверху, помеченной атрибутом холодный.

Я знаю, что glibc генерирует некоторые системные вызовы, но не нахожу в glibc/sysdeps/unix/syscalls.list интересных для себя функций.

Я также извлек функции холодный из libc.a:

cd /usr/lib/x86_64-linux-gnu/
readelf -a --wide libc.a | egrep '\.cold' | awk '{print $NF}' > libc.a.cold

и сравнил их с readelf -a --wide hello | egrep '\.cold' | awk '{print $NF}' > hello.readelf:

grep -f libc.a.cold hello.readelf

Это согласованные функции:

__assert_fail_base.cold
_nl_load_domain.cold
_IO_new_fclose.cold
_IO_fflush.cold
_IO_puts.cold
_IO_wfile_underflow.cold
_IO_new_file_underflow.cold
_IO_fputs.cold
_IO_fwrite.cold
_IO_getdelim.cold
__printf_fp_l.cold
__printf_fphex.cold

А с grep -f libc.a.cold hello.readelf -v я нашел непревзойденные функции:

read_encoded_value_with_base.cold
base_of_encoded_value.cold
execute_cfa_program.cold
uw_frame_state_for.cold
uw_install_context_1.cold
execute_stack_op.cold
uw_update_context_1.cold
uw_init_context_1.cold
uw_update_context.cold
_Unwind_RaiseException_Phase2.cold
_Unwind_GetGR.cold
_Unwind_SetGR.cold
_Unwind_Resume.cold
_Unwind_Resume_or_Rethrow.cold
size_of_encoded_value.cold
base_from_object.cold
base_from_cb_data.cold
read_encoded_value_with_base.cold
_Unwind_IteratePhdrCallback.cold
search_object.cold
base_of_encoded_value.cold
read_encoded_value_with_base.cold

Вопросы:

  1. Может кто-нибудь помочь мне выяснить, где я могу найти исходный код функций холодный?
  2. Где находится исходный код несопоставимых функций из libc.a и бинарника hello и из какой библиотеки они загружены?

Версии:

  • glibc: ldd (Ubuntu GLIBC 2.31-0ubuntu9.7) 2.31

  • гкк: gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0

  • дистрибутив линукс:

    DISTRIB_ID=Ubuntu
    DISTRIB_RELEASE=20.04
    DISTRIB_CODENAME=focal
    DISTRIB_DESCRIPTION = "Ubuntu 20.04.4 LTS"
    
  • Ядро: 5.13.0-41-generic

github.com/lattera/glibc/blob/master/assert/assert.c#L47github.com/lattera/glibc/blob/… как вы искали? github.com/lattera/glibc/blob/… Я имею в виду, просто введите функцию в github, прокрутите до определения, введите. after all of this actions I cannot find any functions from above marked with cold atribute Итак, как вы искали? Простой grep -R должен дать вам результаты.
KamilCuk 16.05.2022 18:22

@KamilCuk это не то, что ищет ОП. ОП хочет понять, откуда взялся .cold, поскольку в исходном коде такой атрибут не объявлен.

Marco Bonelli 16.05.2022 18:31
Стоит ли изучать 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
2
81
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

where I can find a source code of cold functions?

В исходном коде glibc.

I cannot find any functions from above marked with cold atribute

Это очень странно, достаточно простого grep -R, но вас может заинтересовать индексация кода - clangd, GLOBAL теги, ctags и т. д. Вы можете заинтересовать себя в the_silver_searcher для более быстрого grep.

$ git clone git://git.launchpad.net/ubuntu/+source/glibc
Cloning into 'glibc'...
...
$ cd glibc/
$ grep -R --include '*.c' __assert_fail_base
assert/assert.c:__assert_fail_base (const char *fmt, const char *assertion, const char *file,
assert/assert.c:  __assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n%n"),
assert/assert-perr.c:  __assert_fail_base (_("%s%s%s:%u: %s%sUnexpected error: %s.\n%n"),

Итак, __assert_fail_base определяется в assert/assert.c. Вы можете повторить процесс для каждой функции.

Но гораздо проще просто набрать функцию в гугле или найти проект на гитхабе и поискать там. А еще есть https://code.woboq.org/, что делает задачу просто тривиальной.

Where is located source code of unmatched functions from libc.a and hello binary and from which library they loads?

Похоже, внутри libgcc, а Unwind, скорее всего, в gcc-libstdС++.

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

Функции не обязательно должны быть помечены как холодные с помощью __attribute__((cold)), чтобы GCC понял, что они «холодные». GCC может и будет делать это сам, когда включены соответствующие оптимизации.

В частности, цитируя документ GCC по оптимизации:

-freorder-blocks-and-partition

In addition to reordering basic blocks in the compiled function, in order to reduce number of taken branches, partitions hot and cold basic blocks into separate sections of the assembly and .o files, to improve paging and cache locality performance.

This optimization is automatically turned off in the presence of exception handling or unwind tables (on targets using setjump/longjump or target specific scheme), for linkonce sections, for functions with a user-defined section attribute and on any architecture that does not support named sections. When -fsplit-stack is used this option is not enabled by default (to avoid linker errors), but may be enabled explicitly (if using a working linker).

Enabled for x86 at levels -O2, -O3, -Os.

Как видите, эта оптимизация включена по умолчанию в -O2, -O3 и -Os.

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

void parent_function(int x) {
    if (__builtin_expect(x == 1337, 1)) {
        some_function(123);
    } else {
        some_function(456);
    }

    // ...
}

GCC может разбивать some_function (или даже parent_function) на some_function и some_function.cold, упрощая внутреннюю логику функций. Итак, в вашем случае те функции .cold, которые вы видите в скомпилированном двоичном файле, являются нет фактически определенными в исходном коде как таковые, а скорее создаются GCC автоматически.

Для конкретного примера, точная версия __printf_fp_l OP имеет разделы __builtin_expect и __glibc_unlikely. Предположительно, некоторые из них попадают в раздел .cold.

Useless 16.05.2022 19:11

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