| Liste des Groupes | Revenir à cl c |
On 5/31/2026 4:14 AM, David Brown wrote:On 30/05/2026 22:48, BGB wrote:On 5/30/2026 6:52 AM, David Brown wrote:On 29/05/2026 22:16, BGB wrote:On 5/29/2026 6:22 AM, David Brown wrote:On 29/05/2026 12:20, BGB wrote:On 5/29/2026 2:52 AM, Janis Papanagnou wrote:On 2026-05-28 11:57, BGB wrote:On 5/28/2026 2:18 AM, Janis Papanagnou wrote:[...]On 2026-05-28 01:49, BGB wrote:
OK. My code typically has a stack of 1 KB or less per thread. It is not inconceivable that I would have a static array like this, but it would not be in code that is likely to be unused.I have seen this pattern sometimes, though usually in "medium old" code, with newer code more often assuming that the stack is really big and so can handle putting 1MB or more in a local array. Though, this is not great on a target which doesn't have a huge stack.Also functions with large static arrays.>
>
>
void SomeFunc()
{
static char buf[4096];
...
}
>
Where, say, eliminating SomeFunc does not necessarily eliminate buf.
Yes, if you have such code but want to eliminate it, then -fdata- sections would definitely benefit. I have not seen such code in practice (at least not with very big static arrays, and that also was not an essential part of the program). But of course I have only seen a microscopic part of all C code written - if you come across this sort of thing, then I appreciate your point.
>
(There are several ways to make this more "friendly" to builds that need to be compact, such as putting the buffer and/or SomeFunc in a separate file or giving it a specific section of its own.)
>
In my case, I usually had 128K as the default stack size in my project.
Thanks. That clears things up for me. And in particular, it shows that section anchors (and therefore no "-fdata-sections") can make a significant difference to gcc code for RISC-V.It can use one of two strategies for these (after breaking up pseudo- instructions):>>>
Where section anchors shine - and where -fdata-sections therefore has cost - is when a function needs to access more than one piece of static lifetime data defined in the same translation unit (or another translation unit if you are using LTO). That happens a lot in embedded ARM programming at least. I don't know about RISC-V. If the target normally uses a "small data section" for ram (I know this is common on PowerPC), then there is, in effect, a program-wide section anchor already. So it is possible that it relatively few targets have section anchors - but the 32-bit ARM on gcc is a vastly popular choice in the embedded world, so it is important to understand the cost of this compiler flag for that target at least.
>
It depends on the way it is built.
>
>
A lot of times though (for non-relocatable static-linked binaries) it mostly tends to use AUIPC+LD or AUIPC+ST pairs to access global variables. There is a Global Pointer that needs to be loaded when the binary is started, unclear what it is used for exactly.
>
If you have a global pointer, then it will probably be used for gp+offset access to global data, eliminating the need for section anchors.
>
I have not used RISC-V, and am not familiar with its details. I can see from godbolt that when -fdata-sections is in action and you are loading from static lifetime variables, the compiler generates instructions like
>
lw a5, a_variable
lw a4, b_variable
lw a0, c_variable
>
When you do not have "-fdata-sections", it uses anchors :
>
lla a4, .LANCHOR0
lw a5, 0(a4)
lw a3, 4(a4)
lw a0, 8(a4)
>
From my (limited) understanding, RISC-V cannot use 32-bit absolute addressing. So the "lw a5, a_variable" must be a pseudo-instruction - using register + offset addressing. If there is a global pointer, then presumably that is used here. Alternatively, the pseudo instruction might assemble to two real instruction to support the 32- bit address. I know both techniques are used in some targets, but don't know about RISC-V.
>
LUI a5, HiAddr //Abs32, Low 2GB only
LW a5, LoAddr(a5)
Or:
AUIPC a5, HiAddr //PC-Rel
LW a5, LoAddr(a5)
IIRC, LLA is similar, just using an ADDI as the second instruction.
But, yeah, the latter sequence would be more efficient.
I would expect something different if building with -fPIC or -fPIE, but this depends on if it is a version of GCC built with support for these (if using a version of GCC built for non-hosted targets, it ignores these). Where, one effectively needs different GCC builds for bare-metal (like OS kernels) and for hosted Linux development, for whatever bizarre reason...[...]
Certainly it would surprise me if the "lw a5, a_variable" version were more efficient than using anchors - otherwise why would gcc generate code with anchors when given a free choice? (Perhaps gcc is not well tuned for RISC-V code generation - I am wary of making too many assumptions about the processor just from some simple compiler outputs.)It is not, it is a 2-op sequence usually.
>
Plain RISC-V has a bigger problem with 64-bit constants though, generally needs to either load these from memory (more typical in GCC) or build them in-place (which needs roughly 6 instructions in RISC-V).
Say (possible, but GCC doesn't do this):
LUI t0, ValHiA
LUI t1, valHiB
ADDI t0, t0, valLoA
ADDI t1, t1, valLoB
SLLI t1, t1, 32
ADD a0, t0, t1
In my case, I have extensions for RV that can turn a lot of this stuff into single instructions (albeit with larger 8 and 12 byte encodings).
In some cases, it can save bytes, for example:
LW a1, Disp33s(a0)
As a 64-bit / 8-byte encoding, vs:
LUI t0, DispHi
ADD t0, t0, a0
LW a1, DispLo(a0)
Needing 12 bytes.
My own (more drastic) extensions can save more, by having a few Disp16 instructions, which can access 256K or 512K past GP within a single 32- bit instruction.
But, if/when any of this would end up in mainline RISC-V is uncertain.
Weirdly, there is a lot more emphasis there on big/fancy features (with niche applicability), rather than on smaller things that can improve the properties of the base ISA (and that could more generally benefit nearly all code built for the ISA).
Note that MinGW and Mingw-w64 are very, very different. (And the corresponding environments and utility collections, msys and msys2, are equally different.) Mingw-w64, as I understand it, is somewhat of a balance between old MinGW and Cygwin in being close to native for most purposes, but providing more POSIX compliance than MinGW. It is also much newer, much better maintained, with modern language support in its tools (last I heard, with MinGW you did not even get C99 support in the standard library). And of course it has 64-bit support.>Yes, I had used MinGW for a while, before mostly moving over to MSVC for native Windows.
Cygwin has its own wide range of complications. If you want to use gcc targeting native Windows, msys2 and mingw-64 are probably your best bet, either compiled natively under msys2 or as a cross-compile from Linux. But don't place too much emphasis on my advice, as I very rarely compile C or C++ code for Windows - most of my PC target (Linux or Windows) coding is in Python.
>
The tradeoff is mostly:
MinGW is closer to native for Windows;
Cygwin could give a closer approximation of Linux on Windows, so one can build a lot of Linux software and use "./configure" scripts and similar.
But, as noted, Cygwin's role was mostly displaced by WSL, which effectively runs a Linux userland on Windows.
There was WSL1, which basically mapped Linux syscalls over to the Windows kernel, and WSL2, which runs the Linux kernel in a VM.
Though, in my case I was using WSL1 as seemingly MS had decided that my PC can't do virtualization (and sees it as necessary for WSL2), even despite having a CPU that can do so, and it is enabled in the BIOS.
Les messages affichés proviennent d'usenet.