Это имеет смысл для компилятора пройти структуру, подобную этому в регистре процессора в функцию?

StackOverflow https://stackoverflow.com/questions/4213107

Вопрос

Я хотел бы знать, если какая-то структура содержит более одного примитивного, но его общий размер меньше или равен размеру одного регистра CPU, как 4-байтовый регистр, это имеет смысл для компилятора, чтобы сделать его в одном из этих 4 байтовых регистров при прохождении его по значению или ссылке на функцию вместо того, чтобы сделать копию ее на стеке Callee или передачу на него указателя и в общем, при прохождении чего-то более одного примитива к функции Массив или структура пройдут в реестре процессора, когда-либо пригодились?

Образец такой структуры:

struct sample{
 public:
  char char1;
  char char2;
};

Образец передачи структуры к функции:

void someFunc(const sample input){
 //whatever
}
void someFunc(sample input){
 //whatever
}
void someFunc(sample & input){
 //whatever
}
void someFunc(const sample & input){
 //whatever
}
Это было полезно?

Решение

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

Обычно вы используете его только для структуры, который такой же размер, как родной реестр. В частности, это полезно для процессоров, которые имеют широкие регистры SIMD, которые могут пропустить 16 байтов за раз или более. Это позволило бы вам пройти (например) 4-мерное вектор (четыре поплавка) на одном регистре. Система AMD V является примером X86 ABI, который позволяет этому.

Другим примером является атрибут типа D64_ABI типа D64_ABI, который сообщает PowerPC пройти структуру на регистрах, где это возможно, а не на стеке. (Это часть Дарвин Аби.).

typedef struct {
    int          a;
    float        f;
    char         c;
} __attribute__ ((d64_abi)) Thingy;

Thingy foo( Thingy t );

В случае выше, призыв к FOO переданет Thingy на одном флотском регистре и два регистров INT, вместо того, чтобы писать его в стек и чтение его обратно. Возвращаемое значение возвращается на регистры так же.

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

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

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

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

На определенных архитектурах (например, I386, я знаю, что это древнее, но это то, с чем я вырос;) Это, безусловно, имеет смысл пройти в реестре, поскольку нажатие и выскакивание из стека, возьмите на себя гораздо больше (скажем, в возрасте от 3 до 6 раз. Больше) ЦП циклов CPU, как проходит мимо регистрации. Таким образом, компилятор сделает хорошую работу оптимизации для этого.

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

Какую архитектуру вы используете / Tarching, или вы спрашиваете в целом?

Я думаю, что есть компиляторы, которые пройдут стручки в регистрах, даже если они structс.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top