Это имеет смысл для компилятора пройти структуру, подобную этому в регистре процессора в функцию?
-
26-09-2019 - |
Вопрос
Я хотел бы знать, если какая-то структура содержит более одного примитивного, но его общий размер меньше или равен размеру одного регистра 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
с.