cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Дать возможность безопасно и с нулевым оверхедом использовать runtime-cpu-detection #332

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +1, -1 Автор идеи: ilnurkh

  1. добавить std::cpu_info_t содержащий информацию о доступных инструкциях (avx sse и т.п.)
  2. дать возможность без накалдных расходов на virtaul-call писать что-то вида
    
    using func_ptr_t = float(float*, float*);
    static const func_ptr_t fastest_host_dot_product_impl = get_fastest_host_dot_product_impl(std::get_host_cpu_info());

func_ptr_t constexpr get_host_cpu_info(std::cpu_info_t cpu_info) { if (cpu_info.have_avx()) { return &avx_dot_product_impl; } if (cpu_info.have_sse4()) { return &sse4_dot_product_impl; } return &trivial_dot_product_impl; }



Есть важная проблема: невозможность максимальной оптимизации в compile-time так как не извеснтно под какую архитектуру компилируется приложение (парк машин не гомогенен, либо список пользователей широк).

Это можно решать через jit (не выглядит как вариант для плюсов) или через cpu-detection непосредственно на хосте.

Во втором случае не избежать накладных расходов:

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

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

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

В качестве ограничения предлагаю разрешить для такого механизма только constexpr функции с единственным аргументом std::cpu_info_t и возвращаемым значением - указатель на функцию.

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

Отдельно хочется добавить, что std::cpu_info_t cpu_info важна сама по себе, оно позволило бы даже без спец механизма помогать компилятору выкидывать ненужные ветки, сопоставляя условия с параметрами компиляции.
apolukhin commented 3 years ago

yndx-antoshkka, 23 июля 2018, 14:05 У GCC есть близкий механизм https://gcc.gnu.org/wiki/FunctionMultiVersioning

Он вам подходит, или требуется что-то ещё?

Саша Зайцев, 23 июля 2018, 17:17 yndx-antoshkka, ты сам ответил на свой вопрос - он только у GCC :-)

ilnurkh, 23 июля 2018, 20:19 yndx-antoshkka, gcc only не подходит

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

Андрей Руссков, 31 июля 2018, 18:02 чтобы не тащить в стандарт все архитектуры и наборы команд, подобный функционал можно сделать аттрибутами (как у gcc, то, что кидал Антон), либо через функции аля bool cpu_supports(string_view) / bool cpu_target_is(string_view) / ...