Strengthen GCC to discard certain global variables

Is there a way to tell GCC not to initialize a specific global array to zero?

I want to reserve a large chunk of memory for storing a large data structure that my code manages, so I say:

#define SIZE_16_MB 0x01000000 BYTE mChunkSpace[SIZE_16_MB]; 

The problem is that crtinit () takes a million years to initialize this space to zero, and this is not necessary at all.

Is there a way to make it not initialize this space?

I am currently hard-coded for a memory address that is outside of what the linker knows, but this is not a particularly reliable way to do something.

Also, this is a slow built-in proc (50MHz Microblaze), so don't assume I'm talking about a PC. It really takes a long time to reset this space.

+6
source share
5 answers

You can use gcc attributes to store the object in another new memory section, for example, in the .noinit section of memory.

  BYTE mChunkSpace[SIZE_16_MB] __attribute__ ((section (".noinit"))); 
+6
source

Try dynamic initialization:

 BYTE* mChunkSpace = (BYTE*)malloc(SIZE_16_MB * sizeof(BYTE)); 

Then this data is not initialized and waits for you to initialize it.

+4
source

Most of the answers you get here on SO will be biased towards Visual Studio or GCC, both on general purpose platforms (like PCs, be it Windows or Linux), and will greatly influence the “standard says ...” quotes , none of which are applicable to small embedded systems, unless you are using embedded Linux or Windows CE.

The ouahs answers are probably the closest to what you need ... maybe EXACTLY what you need if you really use GCC. Since the piece of memory you want is so large that it probably consumes the lion's share of your system memory, it’s best to define a special section in the linker linker assembly file or linker directors in the C, C ++ or assembly file, the syntax for this depends compiler. If you use linker directives in the source / assembly file, you may need to specify read / write attributes of the memory area, etc. Or maybe not, if Microblaze does not have an MMU / memory controller, you need to place the linker symbol at the beginning of the section, and use the extern char symName [] "directive in your C code so that your C code can compile in relocs, which the linker will be rewritten with the actual address of the section. Depending on the compiler and architecture, you may also need to declare symName [] extern with some kind of “distant” attribute; I don't know enough about Microblaze to say anything about it.

+2
source

I would think that non-static memory is not initialized to zero by default?

0
source

The standard states that static data that is not explicitly initialized at the declaration point will be initialized to zero. You can avoid runtime initialization by independently initializing the first element with a nonzero value:

 #define SIZE_16_MB 0x01000000 BYTE mChunkSpace[SIZE_16_MB] = {1}; 

Note that if you specify 0 , the compiler will most likely just save it in the .bss section anyway, i.e. it will still be initialized at runtime. It does not need to be done, but it would be foolish not to do it. So now your array falls into the .data segment.

Of course, this will make the resulting executable much larger (more than 16 MB more), but the memory will not be initialized at run time. So the question comes down to what suits you; the time required to zero this memory or the final size of the executable file?

-2
source

Source: https://habr.com/ru/post/918895/


All Articles