Почему gfortran создает такой большой размер стека по сравнению с C ++ в этой простой программе? - PullRequest
4 голосов
/ 25 апреля 2019

Я собирал несколько простых программ в ассемблер из C ++ и Fortran, чтобы попытаться получить более высокую оценку компьютерной архитектуры.Я написал очень простую программу как на C ++, так и на Фортране, чтобы произвести вывод и затем вернуть.Я не понимаю, почему компилятор Фортрана (gfortran) создает сборку, которая создает такой большой кадр стека по сравнению с C ++.

f_subroutines.f

      PROGRAM F_SUBROUTINES
      CALL SAY_HELLO
      CALL SAY_GOODBYE

      END

      SUBROUTINE SAY_HELLO
        PRINT '(A6)', "Hello."
      END

      INTEGER*4 FUNCTION GET_MY_NUMBER()
        GET_MY_NUMBER = 3
      END

      SUBROUTINE SAY_GOODBYE
        INTEGER :: GET_MY_NUMBER
        PRINT '(A18, I1, A19)',
     1 "Here's my number: ", GET_MY_NUMBER(), ". Call me. Goodbye!"
      END

cpp_subroutines.cpp

#include <cstdio>

void say_hello()
{
    std::printf("Hello.\n");
}

int get_my_number()
{
    return 3;
}

void say_goodbye()
{
    std::printf("Here's my number: %d. Call me. Goodbye!\n", get_my_number());
}

int main()
{
    say_hello();
    say_goodbye();
    return 0;
}

Makefile

CPPFLAGS=-O0
all: cpp_subroutines cpp_subroutines.s f_subroutines f_subroutines.s
cpp_subroutines: cpp_subroutines.o
    $(CXX) $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
cpp_subroutines.s:
    $(CXX) $(CPPFLAGS) -S cpp_subroutines.cpp
f_subroutines: f_subroutines.o
    $(FC) -o $@ $^ $(LDFLAGS)
f_subroutines.s:
    $(FC) -S f_subroutines.f
.PHONY: clean
clean:
    $(RM) cpp_subroutines cpp_subroutines.o cpp_subroutines.s \
          f_subroutines f_subroutines.o f_subroutines.s

cpp_subroutines.s: say_hello

_Z9say_hellov:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %edi
    call    puts
    nop
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc

f_subroutines.s: say_hello

say_hello_:
.LFB2:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $480, %rsp
    movq    $.LC0, -472(%rbp)
    movl    $8, -464(%rbp)
    movq    $.LC4, -408(%rbp)
    movl    $4, -400(%rbp)
    movl    $4096, -480(%rbp)
    movl    $6, -476(%rbp)
    leaq    -480(%rbp), %rax
    movq    %rax, %rdi
    call    _gfortran_st_write
    leaq    -480(%rbp), %rax
    movl    $6, %edx
    movl    $.LC5, %esi
    movq    %rax, %rdi
    call    _gfortran_transfer_character_write
    leaq    -480(%rbp), %rax
    movq    %rax, %rdi
    call    _gfortran_st_write_done
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc 

Я используюgfortran и gcc версии 5.4.0.

Я не совсем уверен, что здесь делает сборка Фортрана:

    subq    $480, %rsp
    movq    $.LC0, -472(%rbp)
    movl    $8, -464(%rbp)
    movq    $.LC4, -408(%rbp)
    movl    $4, -400(%rbp)
    movl    $4096, -480(%rbp)
    movl    $6, -476(%rbp)
    leaq    -480(%rbp), %rax

Кажется, для этого кадра стека используется 480 байт и

  • Имя исходного файла (.LC0) 8 байтов снизу
  • Значение 13 16 байтов снизу
  • Спецификатор формата '(A6)'(.LC4) 64 байта снизу
  • Значение 4 80 байтов снизу
  • Значение 4096 (размер страницы?) Внизу
  • Значение 6 4байтов снизу.

Я очень доволен выводом компиляции C ++, но мне хотелось бы знать why

  • Компиляция Fortran создает такой большой кадр стека.
  • Для чего существуют значения $ 8, $ 4, $ 4096 и $ 6.

1 Ответ

4 голосов
/ 29 апреля 2019

Это давняя проблема в GFortran, подробности см. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48419.

...