理解内存(2)

本文深入探讨了程序中数据的存储类别与作用域概念,以及编译过程如何将指令和数据转换为可执行文件的不同段落。通过比较C和Fortran语言在处理全局和局部数据、静态和自动存储类上的差异,展示了编译器如何管理和优化内存使用。进一步分析了ELF格式文件中各段的大小,揭示了数据和未初始化数据在实际应用中的存储情况,澄清了数据和bss段的共同作用。最后,强调了理解这些技术细节对于高效编程和优化内存利用的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Storage Class and Scope

程序包括可执行语句和数据声明。 Eachdatum has a property known as storage class that reflects its lifespanduring program execution. A related property called scope characterizesthe extent of a datum's visibility. Storage class and scope are assumed fromthe location of a datum's declaration, and determine its placement withinvirtual memory.

In C, data declared outsidethe body of any function have global scope and static (permanent) duration.Although initial values may be assigned, global data are usually uninitialized.Meanwhile, data declared inside the body of a function—including main()—have local scope and automatic (temporary) duration.A local datum can be made permanent by qualifying its declaration with the static keyword so that it retains its value between functioninvocations.

In Fortran, all data are localin scope unless they are declared in a module (Fortran 90/95) or appear in anamed common block. Furthermore, by assigning the SAVE attribute to module variables and by referencingcommon blocks in a SAVEstatement (or carefully locating common block specifications), they effectivelyacquire global scope and static duration. In the case of the Portland Group(PGI) Fortran compilers pgf77 and pgf95, local explicit-shaped arrays (thosefor which fixed bounds are explicitly specified for each dimension) have thestatic, rather than automatic, storage class. However, the contents of sucharrays are invalidated between subroutine invocations, unless they are declaredwith the SAVEattribute or they appear in a SAVEstatement.

Be aware that the treatment of explicit-shaped arrays differs amongcompilers. In contrast to pgf95, the IBM compiler xlf95, for example, considersthem automatic. If necessary, these semantics can be altered with compileroptions.

Program Size

编译器把程序的可执行语句翻译成CPU指令,并且把声明的静态变量翻译成特殊的数据格式。为了制作一个可执行文件,系统的连接器分别把指令和数据聚合成不同的段。所有的指令被放到一个被称为text的段中。遗憾的是这个名字会使人误解为这个段中包含了源代码,其实并不是这样的。同时数据被分成了两个段。一个被称为数据区它放置了初始化了的静态变量。另一个被成为bss,用来存放没有被初始化的静态数据。Bss代表“从符号开始的块”,Bss once stood for "blockstarted from symbol," which was a mainframe assembly language instruction,but the term carries no meaning today.

Consider the following simpleC program, and the equivalent Fortran 90/95 version, in which the major datacomponent is an uninitialized static array of 200 million bytes.

/**

 * simple.c

 */

#include <stdio.h>

#include <stdlib.h>

 

#define NSIZE 200000000

 

char x[NSIZE];

 

int

main (void)

{

 for (int i=0; i<NSIZE; i++)

    x[i] = 'x';

 

 printf ("done\n");

 

 exit (EXIT_SUCCESS);

}

$ pgcc -c9x -o simplesimple.c

$ size simple

   text   data    bss         dec         hex       filename

   1226   560     200000032   200001818  bebc91a   simple

  

$ ls -l simple

-rwxr-xr-x  1 esumbar uofa 7114 Nov 15 14:12 simple

!

! simple.f90

!

module globals

 implicit none

 integer, parameter :: NMAX = 200000000

 character(1), save :: x(NMAX)

end module globals

 

program simple

 use globals

 implicit none

 integer :: i

 

 do i = 1, NMAX

     x(i) = 'x'

 end do

 print*, "done"

 stop

end program simple

$ pgf95 -o simplesimple.f90

$ size simple

   text   data    bss         dec         hex       filename

   77727  1088772 200003752   201170251   bfd9d4b  simple

  

$ ls -l simple

-rwxr-xr-x  1 esumbar uofa 1201694 Nov 15 14:12 simple

 

$ file simple

simple: ELF 64-bit LSBexecutable, AMD x86-64, ...

Compiling (and implicitlylinking) as illustrated above produces an executable program file in the ELF(Executable and Linking Format) format. Running the size command extracts themagnitude of the text, data, and bss segments from the ELF file.

In both cases, the bss segmentis indeed 200 million (plus some administrative overhead). The program'scontribution to the data segment includes only two string literals and onenumeric constant, which does not account for the sizes reported. Apparently, thecompilers are responsible for the discrepancy.

Furthermore, because the ELFfile contains all of the program instructions and all of the initialized data,the sum of the text and data segments should approach, but never exceed, thesize of the file on disk. Reserving space for the bss segment in the file isunnecessary since there are no values to store. This is confirmed by theexamples.

Be awarethat the data and bss segments are frequently referred to collectively as justdata, occassionally leading to confusion. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值