2016-09-28 8 views
1

Мой вопросLinux 64bit call конвенция использует регистр для передачи этого «указателя», но код менее эффективен?

Из википедии 64 бит API вызова условность использует регистры для передачи первых параметров в RDI, Риши и т.д.

Но я нашел: 64 бит, при вызове функции-члена класса (например конструктор), код, сгенерированный компилятором, переместит «этот» указатель из регистра в память, и вызов функции будет использовать эту память.

Таким образом, я чувствовал: использование регистра (в качестве посредника) является излишним.

Эксперимент

Обратите внимание на конструктор, порожденную НКУ и проверить разборку с помощью GDB. Первый 32-разрядный.

struct Test 
{ 
    int i; 
    Test(){ 
    i=23; 
    } 
}; 
int main() 
{ 
    Test obj1; 
    return 0; 
} 

$ gcc Test.cpp -g -o Test -m32 

GDB, чтобы начать его, разрыв на уровне 'я = 23', проверьте разборку:

(gdb) disassemble 
Dump of assembler code for function Test::Test(): 
    0x08048484 <+0>: push %ebp 
    0x08048485 <+1>: mov %esp,%ebp 
=> 0x08048487 <+3>: mov 0x8(%ebp),%eax #'this' pointer in%ebp+8, passed by caller 
    0x0804848a <+6>: movl $0x17,(%eax) #Put "23" at the first member location 
    0x08048490 <+12>: nop 
    0x08048491 <+13>: pop %ebp 
    0x08048492 <+14>: ret  
End of assembler dump. 

Вопрос (1)

Это 32-битная версия кажется эффективным. Но «этот» указатель не передается регистром «ecx», как VC. Использует ли gcc «ecx» для хранения «этого» указателя?


Тогда 64bit:

(gdb) disassemble 
Dump of assembler code for function Test::Test(): 
    0x0000000000400584 <+0>: push %rbp 
    0x0000000000400585 <+1>: mov %rsp,%rbp 
    0x0000000000400588 <+4>: mov %rdi,-0x8(%rbp) #rdi to store/ restore 'this' 
=> 0x000000000040058c <+8>: mov -0x8(%rbp),%rax #Same as 32 bit version. 
    0x0000000000400590 <+12>: movl $0x17,(%rax) 
    0x0000000000400596 <+18>: nop 
    0x0000000000400597 <+19>: pop %rbp 
    0x0000000000400598 <+20>: retq 
End of assembler dump. 

Вопрос (2)

На этот раз, больше инструкций, то ход 'этого' указателя от% RDI памяти, кажется, указывает , Использование регистра бесполезно, потому что finnaly должно быть внутри памяти, чтобы быть параметром функции.

(2.1) Для 64 бит первые 2 параметра вызова функции хранятся в rdi, rsi. Но здесь нет необходимости в rdi хранить «этот» указатель и снова восстанавливать его в памяти. Мы могли бы «нажимать» этот указатель непосредственно, и конструктор мог бы его использовать.

(2.2) И для 64-битной программы требуется дополнительное слово size_t (% rbp-8) в стеке для восстановления указателя «this».

В общем, экономичность пространства и времени 64-битной версии стоит 32 бит. Это связано с 64-битным соглашением о вызове или просто потому, что я не говорю gcc о том, чтобы оптимизировать код до последнего бита его силы?

Когда скорость 64 бит?

Оцените свои предложения. Огромное спасибо.

+10

Этого рода соображение о производительности на уровне инструкций бессмысленно, если вы не включаете оптимизацию. Возможно, вы захотите включить оптимизацию ('-O') и снова начать сравнение. – ysdx

ответ

1

на самом деле, оптимизатор стирает весь код

даже изменяя основной для возврата obj1.i код Test :: Test() оптимизирован для нулевого значения:

0000000000400470 <main>: 
    400470: b8 17 00 00 00   mov $0x17,%eax 
    400475: c3      retq 

 Смежные вопросы

  • Нет связанных вопросов^_^