Могу ли я контролировать распределение регистров в g ++? - PullRequest
5 голосов
/ 11 февраля 2009

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

Ответы [ 3 ]

6 голосов
/ 11 февраля 2009

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

Вы делаете это с помощью специального объявления переменной, подобного этому:

 register int test_integer asm ("EBX");

Работает и для других архитектур, просто замените EBX на целевое имя регистра.

Для получения более подробной информации, я предлагаю вам взглянуть на документацию gcc:

http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Local-Reg-Vars.html

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

Если ваша функция настолько критична по производительности, что вы получаете 20% -ную разницу в производительности между компиляциями, было бы неплохо написать эту вещь в inline-ассемблере.


РЕДАКТИРОВАТЬ: Как указал strager, компилятор не обязан использовать регистр для переменной. Использовать регистр только принудительно, если переменная используется вообще. Например. если переменная не переживает проход оптимизации, она не будет использоваться. Также регистр можно использовать и для других переменных.

3 голосов
/ 11 февраля 2009

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

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

0 голосов
/ 11 февраля 2009

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

...