Оптимизация для деления на "extern const int" - PullRequest
3 голосов
/ 16 декабря 2009

Я работаю в проекте, в котором у меня есть следующий код:

file1.c

extern const int z;
int x;
do_some_stuff_to_calculate_x();
y = x / z;
do_some_stuff_with_y();

file2.c

const int z = Z_INIT_VALUE; // some value defined in some .h file.

Интересной точкой является деление на file1.c. Поскольку z равно extern, поэтому оно не известно во время компиляции [оно будет определено во время компоновки]. Таким образом, компилятор не может оптимизировать деление.

Я знаю, что если во время компиляции известно значение z, компилятор преобразует деление в умножение и некоторые другие манипуляции.

Обратите внимание, что file1.c будет доставлен в виде библиотеки, поэтому перекомпиляция file1.c с file2.c не подходит.

Кто-нибудь знает, чтобы компоновщик оптимизировал такие вещи? Или любой другой трюк, чтобы избежать этого ДОРОГОГО подразделения?

Thx:)

Обновление:

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

  • Я использую микроконтроллер от компании renesas (Семейство SH725).
  • Это разделение встречается в МНОГИХ местах кода, со многими вариантами.
  • Большинство других вещей в коде - это прямое чтение и запись в регистры и порты (без накладных расходов, т.е.: * 0x0ABCDEFF = 15).

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

extern const int common_divisor;
extern const int common_addition;

void handleTheDamnInterrupt(void)
{
    int x = *(REG_FOO_1);
    int y = x / common_divisor;
    y += common_addition;
    if( x > some_value )
    {
       y += blah_blah;
    }
    else
    {
       y += foo_bar;
    }

    *(REG_BAR_1) = y;
}

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

Ответы [ 4 ]

3 голосов
/ 16 декабря 2009

Вы можете выполнить ту же оптимизацию самостоятельно, выполнив некоторые настройки во время инициализации. Алгоритм, разработанный Терье Матизеном для преобразования целочисленного деления в умножение, описан здесь: http://www.asdf.org/~fatphil/x86/pentopt/27.html

2 голосов
/ 16 декабря 2009

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

Если z действительно является константой и инициализируется из символа препроцессора, просто поместите этот символ в заголовок библиотеки и вообще перестаньте представлять его как переменную времени выполнения.

2 голосов
/ 16 декабря 2009

Компоновщик Microsoft, например, оптимизирует это . Это называется "генерация кода времени соединения". Вот статья об этом (от, но все еще полезная). Включается с флагом /LTCG .

0 голосов
/ 16 декабря 2009

Ваши звонки на do_some_stuff значительно перевесят целочисленное деление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...