Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #68773 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2019-09-30 14:02 +0200 |
| Last post | 2019-10-05 14:08 -0700 |
| Articles | 20 on this page of 110 — 21 participants |
Back to article view | Back to comp.lang.c++
alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 14:02 +0200
Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-09-30 07:02 -0700
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 16:09 +0200
Re: alloca()-support Bo Persson <bo@bo-persson.se> - 2019-09-30 17:29 +0200
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 17:33 +0200
Re: alloca()-support gazelle@shell.xmission.com (Kenny McCormack) - 2019-09-30 16:26 +0000
Re: alloca()-support Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-09-30 17:12 +0300
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 16:16 +0200
Re: alloca()-support Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-09-30 17:30 +0300
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 16:44 +0200
Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-02 00:36 +0300
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:28 +0200
Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-02 16:08 +0300
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 15:42 +0200
Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 14:30 +0000
Re: alloca()-support Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-09-30 17:33 +0300
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-09-30 16:56 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-09-30 15:29 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 17:31 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-01 07:03 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 10:57 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-01 18:49 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 21:20 +0200
Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-01 20:39 +0000
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:15 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:28 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:29 +0000
Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-09-30 11:14 -0700
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 18:04 +0200
Re: alloca()-support William Ahern <william@25thandClement.com> - 2019-09-30 11:01 -0700
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:19 +0200
Re: alloca()-support Paavo Helde <myfirstname@osa.pri.ee> - 2019-09-30 22:26 +0300
Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 19:46 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:32 +0200
Re: alloca()-support Paavo Helde <myfirstname@osa.pri.ee> - 2019-10-01 09:08 +0300
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 08:35 +0200
Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 18:48 +0200
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 18:51 +0200
Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 18:55 +0200
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 18:58 +0200
Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 19:53 +0200
Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-09-30 11:13 -0700
Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 19:38 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:41 +0200
Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-01 15:19 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 17:31 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-01 18:58 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 21:24 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:28 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:30 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:36 +0000
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:01 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-02 04:42 +0000
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:10 +0200
Re: alloca()-support Mel <mel@zzzzz.com> - 2019-10-02 15:13 +0200
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-01 21:10 +0200
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 21:25 +0200
Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-01 20:44 +0000
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-01 23:26 +0200
Re: alloca()-support Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-10-01 21:08 -0600
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:19 +0200
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 06:39 +0200
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-02 10:34 +0200
Re: alloca()-support Mel <mel@zzzzz.com> - 2019-10-02 15:14 +0200
Re: alloca()-support Mel <mel@zzzzz.com> - 2019-10-02 15:18 +0200
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-02 15:21 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-03 04:09 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-03 07:48 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-03 05:49 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-03 07:52 +0200
Re: alloca()-support Melzzzzz <Melzzzzz@zzzzz.com> - 2019-10-03 06:46 +0000
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-03 10:59 +0200
Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-10-03 13:39 +0200
Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-03 13:23 +0000
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-03 15:38 +0200
Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-10-03 14:51 +0000
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-04 09:49 +0200
Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-10-03 21:47 +0200
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-04 09:53 +0200
Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-10-03 21:52 +0200
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:39 +0200
Re: alloca()-support James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-09-30 21:36 -0400
Re: alloca()-support Philipp Klaus Krause <pkk@spth.de> - 2019-09-30 19:14 +0200
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 19:16 +0200
Re: alloca()-support Robert Wessel <robertwessel2@yahoo.com> - 2019-10-01 00:18 -0500
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 07:43 +0200
Re: alloca()-support Keith Thompson <kst-u@mib.org> - 2019-10-01 02:42 -0700
Re: alloca()-support James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-10-01 08:11 -0400
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-10-01 14:53 +0200
Re: alloca()-support scott@slp53.sl.home (Scott Lurndal) - 2019-09-30 17:52 +0000
Re: alloca()-support Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-09-30 11:20 -0600
Re: alloca()-support Bonita Montero <Bonita.Montero@gmail.com> - 2019-09-30 19:42 +0200
Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 20:02 +0200
Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 19:54 +0200
Re: alloca()-support Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-09-30 14:28 -0600
Re: alloca()-support David Brown <david.brown@hesbynett.no> - 2019-10-01 09:38 +0200
Re: alloca()-support Soviet_Mario <SovietMario@CCCP.MIR> - 2019-09-30 20:01 +0200
Re: alloca()-support Manfred <noname@add.invalid> - 2019-10-01 17:45 +0200
Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-10-02 00:03 -0700
Re: alloca()-support Paavo Helde <myfirstname@osa.pri.ee> - 2019-10-02 11:30 +0300
Re: alloca()-support Ian Collins <ian-news@hotmail.com> - 2019-10-02 21:34 +1300
Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-10-02 01:36 -0700
Re: alloca()-support Ian Collins <ian-news@hotmail.com> - 2019-10-02 21:41 +1300
Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-10-02 02:28 -0700
Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-02 02:35 -0700
Re: alloca()-support Frederick Gotham <cauldwell.thomas@gmail.com> - 2019-10-02 02:43 -0700
Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-02 16:26 +0300
Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-02 12:33 -0700
Re: alloca()-support Anton Shepelev <anton.txt@gmail.com> - 2019-10-03 01:47 +0300
Re: alloca()-support "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2019-10-05 14:08 -0700
Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6 Next page →
| From | Soviet_Mario <SovietMario@CCCP.MIR> |
|---|---|
| Date | 2019-09-30 19:53 +0200 |
| Message-ID | <qmtfeh$gno$1@dont-email.me> |
| In reply to | #68801 |
On 30/09/2019 18:58, Bonita Montero wrote: >>>> Since when (if at any time) was variable size automatic >>>> array supported ? > >>> Since C99. > >> for curiosity, this feature has one or more of the >> limitations I feared ... or even none of them ? > > Yes, you could run out of stack-space, maybe hitting a > guard-page > in the best case so that you wouldn't corrupt any other data. uhm, I didn't mean THAT kind of risk (unavoidable), but the possible difficulties in defining variables beyond the point of declaration of the variable-size array. I can't figure out how the compiler would reference them in standard efficient ways (use of registers). Anyway, the difference with alloca () would be in a safer management of possible collisions and running out of stack space ? (compared with the plain declarations) ? > -- 1) Resistere, resistere, resistere. 2) Se tutti pagano le tasse, le tasse le pagano tutti Soviet_Mario - (aka Gatto_Vizzato)
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-09-30 11:13 -0700 |
| Message-ID | <lneezx3b6b.fsf@kst-u.example.com> |
| In reply to | #68807 |
Soviet_Mario <SovietMario@CCCP.MIR> writes:
> On 30/09/2019 18:58, Bonita Montero wrote:
>>>>> Since when (if at any time) was variable size automatic
>>>>> array supported ?
>>
>>>> Since C99.
>>
>>> for curiosity, this feature has one or more of the
>>> limitations I feared ... or even none of them ?
>>
>> Yes, you could run out of stack-space, maybe hitting a
>> guard-page
>> in the best case so that you wouldn't corrupt any other data.
>
> uhm, I didn't mean THAT kind of risk (unavoidable), but the
> possible difficulties in defining variables beyond the point
> of declaration of the variable-size array.
>
> I can't figure out how the compiler would reference them in
> standard efficient ways (use of registers).
>
> Anyway, the difference with alloca () would be in a safer
> management of possible collisions and running out of stack
> space ? (compared with the plain declarations) ?
No. Neither VLAs nor alloca() provide any protection against running
out of space. Both have undefined behavior if there isn't enough memory
for the allocation.
alloca() (which, again, is non-standard) is a function that returns a
pointer. It has no provision to return a null pointer on failure.
Defining a VLA, on the other hand, creates an array object to which you
can meaningfully apply sizeof.
Also, space allocated by alloca() is deallocated on return from the
enclosing function, not at the end of the enclosing block.
Since alloca() is a function, it can be invoked in contexts where a VLA
can't be created. If you call alloca() as part of a function argument,
it's likely to corrupt the stack.
VLAs were introduced in C99 and made optional in C11 and are not
supported, except perhaps as an extension, in C++.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-09-30 19:38 +0000 |
| Message-ID | <lRskF.22050$XA2.21391@fx05.iad> |
| In reply to | #68807 |
Soviet_Mario <SovietMario@CCCP.MIR> writes:
>On 30/09/2019 18:58, Bonita Montero wrote:
>>>>> Since when (if at any time) was variable size automatic
>>>>> array supported ?
>>
>>>> Since C99.
>>
>>> for curiosity, this feature has one or more of the
>>> limitations I feared ... or even none of them ?
>>
>> Yes, you could run out of stack-space, maybe hitting a
>> guard-page
>> in the best case so that you wouldn't corrupt any other data.
>
>uhm, I didn't mean THAT kind of risk (unavoidable), but the
>possible difficulties in defining variables beyond the point
>of declaration of the variable-size array.
>
>I can't figure out how the compiler would reference them in
>standard efficient ways (use of registers).
mov %rsp, %rax # rax now has starting address of alloca() region
sub %rcx, %rsp # rcx is the number of bytes being allocated.
....
mov %rsp, %rbx # rbx now has starting address of second alloca() region
sub %rdx, %rsp # rdx is the number of bytes being allocated
....
ret # all alloca storage is deallocated
(AT&T form)
It can always spill rax or rbx to the stack under register pressure.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2019-10-01 07:41 +0200 |
| Message-ID | <qmuov1$n71$2@news.albasani.net> |
| In reply to | #68818 |
> mov %rsp, %rax # rax now has starting address of alloca() region The compiler usually uses RPB to remember the frame-pointer-address at the prolog of the function. EBP is more suitable because it can be restored in one step by the x86 LEAVE-instruction. > sub %rcx, %rsp # rcx is the number of bytes being allocated. > ....
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-10-01 15:19 +0000 |
| Message-ID | <J7KkF.4573$KB2.3280@fx02.iad> |
| In reply to | #68830 |
Bonita Montero <Bonita.Montero@gmail.com> writes:
>> mov %rsp, %rax # rax now has starting address of alloca() region
>
>The compiler usually uses RPB to remember the frame-pointer-address
>at the prolog of the function. EBP is more suitable because it can
>be restored in one step by the x86 LEAVE-instruction.
So what? The RSP is restored automatically by the ret instruction.
int f(unsigned long len)
{
char *f = alloca(len);
for (int i=0; i < 0; i++) {
*f++ = '\0';
}
return 0;
}
gcc output:
0000000000400540 <f>:
#include <alloca.h>
#include <stdlib.h>
int f(unsigned long len)
{
400540: 55 push %rbp
400541: 48 89 e5 mov %rsp,%rbp
400544: 48 83 ec 20 sub $0x20,%rsp
400548: 48 89 7d e8 mov %rdi,-0x18(%rbp)
char *f = alloca(len);
40054c: 48 8b 45 e8 mov -0x18(%rbp),%rax
400550: 48 8d 50 0f lea 0xf(%rax),%rdx
400554: b8 10 00 00 00 mov $0x10,%eax
400559: 48 83 e8 01 sub $0x1,%rax
40055d: 48 01 d0 add %rdx,%rax
400560: b9 10 00 00 00 mov $0x10,%ecx
400565: ba 00 00 00 00 mov $0x0,%edx
40056a: 48 f7 f1 div %rcx
40056d: 48 6b c0 10 imul $0x10,%rax,%rax
400571: 48 29 c4 sub %rax,%rsp <===== Alloca(len)
400574: 48 89 e0 mov %rsp,%rax <===== Remember f in %rax
400577: 48 83 c0 0f add $0xf,%rax <===== Align it
40057b: 48 c1 e8 04 shr $0x4,%rax
40057f: 48 c1 e0 04 shl $0x4,%rax
400583: 48 89 45 f8 mov %rax,-0x8(%rbp) <== And save in stack frame
for (int i=0; i < 0; i++) {
400587: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%rbp)
40058e: eb 13 jmp 4005a3 <f+0x63>
*f++ = '\0';
400590: 48 8b 45 f8 mov -0x8(%rbp),%rax
400594: 48 8d 50 01 lea 0x1(%rax),%rdx
400598: 48 89 55 f8 mov %rdx,-0x8(%rbp)
40059c: c6 00 00 movb $0x0,(%rax)
40059f: 83 45 f4 01 addl $0x1,-0xc(%rbp)
4005a3: 83 7d f4 00 cmpl $0x0,-0xc(%rbp)
4005a7: 78 e7 js 400590 <f+0x50>
*f++ = '\0';
}
return 0;
4005a9: b8 00 00 00 00 mov $0x0,%eax
}
4005ae: c9 leaveq
4005af: c3 retq
>
>> sub %rcx, %rsp # rcx is the number of bytes being allocated.
>> ....
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2019-10-01 17:31 +0200 |
| Message-ID | <qmvrfu$j5$1@news.albasani.net> |
| In reply to | #68855 |
>> The compiler usually uses RPB to remember the frame-pointer-address >> at the prolog of the function. EBP is more suitable because it can >> be restored in one step by the x86 LEAVE-instruction. > So what? The RSP is restored automatically by the ret instruction. Yes, but LEAVE does three instructions in one step. Usually this results in the same uOPs, but it is only one slot in the decoder.
[toc] | [prev] | [next] | [standalone]
| From | Melzzzzz <Melzzzzz@zzzzz.com> |
|---|---|
| Date | 2019-10-01 18:58 +0000 |
| Message-ID | <LlNkF.594801$Nw3.562943@fx40.am4> |
| In reply to | #68856 |
On 2019-10-01, Bonita Montero <Bonita.Montero@gmail.com> wrote: >>> The compiler usually uses RPB to remember the frame-pointer-address >>> at the prolog of the function. EBP is more suitable because it can >>> be restored in one step by the x86 LEAVE-instruction. > >> So what? The RSP is restored automatically by the ret instruction. > > Yes, but LEAVE does three instructions in one step. Usually this > results in the same uOPs, but it is only one slot in the decoder. I never saw any compiler that uses `leave`. Especially since RBP doesn't have to be used as optimization... -- press any key to continue or any other to quit... U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi bili naoruzani. -- Mladen Gogala
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2019-10-01 21:24 +0200 |
| Message-ID | <qn095f$3qm$1@news.albasani.net> |
| In reply to | #68862 |
>> Yes, but LEAVE does three instructions in one step. Usually this
>> results in the same uOPs, but it is only one slot in the decoder.
> I never saw any compiler that uses `leave`.
MSVC and gcc always use LEAVE when you have dynamic stack-frames
with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
#include <stddef.h>
void f( size_t s )
{
int volatile a[s];
a[s - 1] = 123;
}
.file "x.c"
.text
.p2align 4,,15
.globl f
.type f, @function
f:
.LFB0:
.cfi_startproc
leaq 18(,%rdi,4), %rax
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
subq $1, %rdi
andq $-16, %rax
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq %rax, %rsp
movl $123, (%rsp,%rdi,4)
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size f, .-f
.ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
.section .note.GNU-stack,"",@progbits
[toc] | [prev] | [next] | [standalone]
| From | Melzzzzz <Melzzzzz@zzzzz.com> |
|---|---|
| Date | 2019-10-02 04:28 +0000 |
| Message-ID | <MHVkF.568895$bS1.507387@fx13.am4> |
| In reply to | #68867 |
On 2019-10-01, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>
>>> Yes, but LEAVE does three instructions in one step. Usually this
>>> results in the same uOPs, but it is only one slot in the decoder.
>
>> I never saw any compiler that uses `leave`.
>
> MSVC and gcc always use LEAVE when you have dynamic stack-frames
> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>
> #include <stddef.h>
>
> void f( size_t s )
> {
> int volatile a[s];
> a[s - 1] = 123;
> }
>
>
> .file "x.c"
> .text
> .p2align 4,,15
> .globl f
> .type f, @function
> f:
> .LFB0:
> .cfi_startproc
> leaq 18(,%rdi,4), %rax
> pushq %rbp
> .cfi_def_cfa_offset 16
> .cfi_offset 6, -16
> subq $1, %rdi
> andq $-16, %rax
> movq %rsp, %rbp
> .cfi_def_cfa_register 6
> subq %rax, %rsp
> movl $123, (%rsp,%rdi,4)
> leave
> .cfi_def_cfa 7, 8
> ret
> .cfi_endproc
> .LFE0:
> .size f, .-f
> .ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
> .section .note.GNU-stack,"",@progbits
Yes, this is against optimisations as you use volatile...
--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2019-10-02 06:30 +0200 |
| Message-ID | <qn1950$hai$3@news.albasani.net> |
| In reply to | #68879 |
>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>
>> #include <stddef.h>
>>
>> void f( size_t s )
>> {
>> int volatile a[s];
>> a[s - 1] = 123;
>> }
>>
>>
>> .file "x.c"
>> .text
>> .p2align 4,,15
>> .globl f
>> .type f, @function
>> f:
>> .LFB0:
>> .cfi_startproc
>> leaq 18(,%rdi,4), %rax
>> pushq %rbp
>> .cfi_def_cfa_offset 16
>> .cfi_offset 6, -16
>> subq $1, %rdi
>> andq $-16, %rax
>> movq %rsp, %rbp
>> .cfi_def_cfa_register 6
>> subq %rax, %rsp
>> movl $123, (%rsp,%rdi,4)
>> leave
>> .cfi_def_cfa 7, 8
>> ret
>> .cfi_endproc
>> .LFE0:
>> .size f, .-f
>> .ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>> .section .note.GNU-stack,"",@progbits
> Yes, this is against optimisations as you use volatile...
I use volatile to prevent the compiler from optimizing away the
function body.
[toc] | [prev] | [next] | [standalone]
| From | Melzzzzz <Melzzzzz@zzzzz.com> |
|---|---|
| Date | 2019-10-02 04:36 +0000 |
| Message-ID | <mPVkF.569662$R83.227680@fx23.am4> |
| In reply to | #68882 |
On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>
>>> #include <stddef.h>
>>>
>>> void f( size_t s )
>>> {
>>> int volatile a[s];
>>> a[s - 1] = 123;
>>> }
>>>
>>>
>>> .file "x.c"
>>> .text
>>> .p2align 4,,15
>>> .globl f
>>> .type f, @function
>>> f:
>>> .LFB0:
>>> .cfi_startproc
>>> leaq 18(,%rdi,4), %rax
>>> pushq %rbp
>>> .cfi_def_cfa_offset 16
>>> .cfi_offset 6, -16
>>> subq $1, %rdi
>>> andq $-16, %rax
>>> movq %rsp, %rbp
>>> .cfi_def_cfa_register 6
>>> subq %rax, %rsp
>>> movl $123, (%rsp,%rdi,4)
>>> leave
>>> .cfi_def_cfa 7, 8
>>> ret
>>> .cfi_endproc
>>> .LFE0:
>>> .size f, .-f
>>> .ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>> .section .note.GNU-stack,"",@progbits
>
>> Yes, this is against optimisations as you use volatile...
>
> I use volatile to prevent the compiler from optimizing away the
> function body.
"
Linus Torvalds has expressed his displeasure in the past over VLA usage
for arrays with predetermined small sizes, with comments like "USING
VLA'S IS ACTIVELY STUPID! It generates much more code, and much slower
code (and more fragile code), than just using a fixed key size would
have done." [6] With the Linux 4.20 kernel, Linux kernel is effectively
VLA-free.[7]
"
--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-10-02 10:01 +0200 |
| Message-ID | <qn1lhf$bsm$1@dont-email.me> |
| In reply to | #68883 |
On 02/10/2019 06:36, Melzzzzz wrote:
> On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>>
>>>> #include <stddef.h>
>>>>
>>>> void f( size_t s )
>>>> {
>>>> int volatile a[s];
>>>> a[s - 1] = 123;
>>>> }
>>>>
<snip>
>>
>>> Yes, this is against optimisations as you use volatile...
>>
>> I use volatile to prevent the compiler from optimizing away the
>> function body.
There are usually better ways to get this, such as giving a return value
that depends on the function inputs. If you have to use "volatile" to
ensure you are generating code that can be examined, then minimise its
use rather than making the whole array volatile.
(In a test function that used the VLA for calculations, gcc still
generated a "leave" instruction.)
> "
> Linus Torvalds has expressed his displeasure in the past over VLA usage
> for arrays with predetermined small sizes, with comments like "USING
> VLA'S IS ACTIVELY STUPID! It generates much more code, and much slower
> code (and more fragile code), than just using a fixed key size would
> have done." [6] With the Linux 4.20 kernel, Linux kernel is effectively
> VLA-free.[7]
> "
>
VLA's with pre-determined small sizes result in /identical/ code to
arrays with fixed sizes.
void foo1(void) {
const int arr_size = 12;
int arr[arr_size];
...
}
void foo2(void) {
#define ARR_SIZE 12
int arr[ARR_SIZE];
...
}
"foo1" has a VLA with a predetermined small size, while "foo2" has a
normal array with fixed size. These are different as far as the C
language is concerned, but identical in the generated code.
I /think/ what Torvalds is trying to say is that if you know that the
size "n" of your VLA is going be at most "max_n", and you know "max_n"
is small, then you should use a fixed size array of size "max_n" instead
of a VLA. I believe that has both advantages and disadvantages. When
the array is of fixed size (i.e., known at compile time - even if it is
technically a VLA) the code for allocating and deallocating the space is
simpler. Code for accessing the contents of the array or other data
might be a little simpler. But it is all just one-time calculations.
Code that is run repeatedly - and if you have an array, you probably
have a loop - is going to be identical.
So you get the trade-off between a few extra instructions for the
variable VLA, balanced against the benefits of reduced cache use from a
smaller array. I'd not like to be categorical about which is best - it
would need measuring.
If the VLA is making the code fragile, then I expect it would be equally
fragile with a fixed size array.
(Fixed size arrays are also easier for analysis of stack usage, if that
is important.)
[toc] | [prev] | [next] | [standalone]
| From | Melzzzzz <Melzzzzz@zzzzz.com> |
|---|---|
| Date | 2019-10-02 04:42 +0000 |
| Message-ID | <4VVkF.657428$t92.267489@fx25.am4> |
| In reply to | #68882 |
On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>
>>> #include <stddef.h>
>>>
>>> void f( size_t s )
>>> {
>>> int volatile a[s];
>>> a[s - 1] = 123;
>>> }
>>>
>>>
>>> .file "x.c"
>>> .text
>>> .p2align 4,,15
>>> .globl f
>>> .type f, @function
>>> f:
>>> .LFB0:
>>> .cfi_startproc
>>> leaq 18(,%rdi,4), %rax
>>> pushq %rbp
>>> .cfi_def_cfa_offset 16
>>> .cfi_offset 6, -16
>>> subq $1, %rdi
>>> andq $-16, %rax
>>> movq %rsp, %rbp
>>> .cfi_def_cfa_register 6
>>> subq %rax, %rsp
>>> movl $123, (%rsp,%rdi,4)
>>> leave
>>> .cfi_def_cfa 7, 8
>>> ret
>>> .cfi_endproc
>>> .LFE0:
>>> .size f, .-f
>>> .ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>> .section .note.GNU-stack,"",@progbits
>
>> Yes, this is against optimisations as you use volatile...
>
> I use volatile to prevent the compiler from optimizing away the
> function body.
Try more realistic example:
float read_val();
float process(int,float*);
float read_and_process(int n)
{
float vals[n];
for (int i = 0; i < n; ++i)
vals[i] = read_val();
return process(n, vals);
}
Where is `leave` now?
--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-10-02 10:10 +0200 |
| Message-ID | <qn1m1i$f8t$1@dont-email.me> |
| In reply to | #68885 |
On 02/10/2019 06:42, Melzzzzz wrote:
> On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> MSVC and gcc always use LEAVE when you have dynamic stack-frames
>>>> with VLAs (gcc) or alloca(). Here's an example of gcc with VLAs:
>>>>
>>>> #include <stddef.h>
>>>>
>>>> void f( size_t s )
>>>> {
>>>> int volatile a[s];
>>>> a[s - 1] = 123;
>>>> }
>>>>
>>>>
>>>> .file "x.c"
>>>> .text
>>>> .p2align 4,,15
>>>> .globl f
>>>> .type f, @function
>>>> f:
>>>> .LFB0:
>>>> .cfi_startproc
>>>> leaq 18(,%rdi,4), %rax
>>>> pushq %rbp
>>>> .cfi_def_cfa_offset 16
>>>> .cfi_offset 6, -16
>>>> subq $1, %rdi
>>>> andq $-16, %rax
>>>> movq %rsp, %rbp
>>>> .cfi_def_cfa_register 6
>>>> subq %rax, %rsp
>>>> movl $123, (%rsp,%rdi,4)
>>>> leave
>>>> .cfi_def_cfa 7, 8
>>>> ret
>>>> .cfi_endproc
>>>> .LFE0:
>>>> .size f, .-f
>>>> .ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
>>>> .section .note.GNU-stack,"",@progbits
>>
>>> Yes, this is against optimisations as you use volatile...
>>
>> I use volatile to prevent the compiler from optimizing away the
>> function body.
> Try more realistic example:
> float read_val();
> float process(int,float*);
> float read_and_process(int n)
> {
> float vals[n];
>
> for (int i = 0; i < n; ++i)
> vals[i] = read_val();
>
> return process(n, vals);
> }
>
> Where is `leave` now?
>
The compiler will use it if it is convenient, and not use it otherwise.
This sample code /does/ generate "leave" with gcc :
int f(int s )
{
int a[s];
for (int i = 0; i < s; i++) a[i] = i;
int t = 0;
for (int i = 0; i < s; i++) t += a[i];
return t;
}
(clang does not generate a "leave" - it generates its usual unrolled
vector monstrosities that are highly efficient for huge loop counts, and
terrible for tiny counts.)
Basically, it seems that "leave" is equivalent to "mov %ebp, %esp" then
"pop %ebp". If the compiler would otherwise have generated these
instructions, then it uses "leave". If not, then it doesn't. "leave"
appears to be marginally more efficient than the separate instructions -
enough so to use it when there is the option, but not enough to go out
of its way to use it.
(The matching "enter" instruction is much slower than manual
manipulation of the registers, and is thus avoided.)
[toc] | [prev] | [next] | [standalone]
| From | Mel <mel@zzzzz.com> |
|---|---|
| Date | 2019-10-02 15:13 +0200 |
| Message-ID | <almarsoft.1283905241101098670@news.albasani.net> |
| In reply to | #68888 |
On Wed, 2 Oct 2019 10:10:26 +0200, David Brown
<david.brown@hesbynett.no> wrote:
> On 02/10/2019 06:42, Melzzzzz wrote:
> > On 2019-10-02, Bonita Montero <Bonita.Montero@gmail.com> wrote:
> >>>> MSVC and gcc always use LEAVE when you have dynamic
stack-frames
> >>>> with VLAs (gcc) or alloca(). Here's an example of gcc with
VLAs:
> >>>>
> >>>> #include <stddef.h>
> >>>>
> >>>> void f( size_t s )
> >>>> {
> >>>> int volatile a[s];
> >>>> a[s - 1] = 123;
> >>>> }
> >>>>
> >>>>
> >>>> .file "x.c"
> >>>> .text
> >>>> .p2align 4,,15
> >>>> .globl f
> >>>> .type f, @function
> >>>> f:
> >>>> .LFB0:
> >>>> .cfi_startproc
> >>>> leaq 18(,%rdi,4), %rax
> >>>> pushq %rbp
> >>>> .cfi_def_cfa_offset 16
> >>>> .cfi_offset 6, -16
> >>>> subq $1, %rdi
> >>>> andq $-16, %rax
> >>>> movq %rsp, %rbp
> >>>> .cfi_def_cfa_register 6
> >>>> subq %rax, %rsp
> >>>> movl $123, (%rsp,%rdi,4)
> >>>> leave
> >>>> .cfi_def_cfa 7, 8
> >>>> ret
> >>>> .cfi_endproc
> >>>> .LFE0:
> >>>> .size f, .-f
> >>>> .ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
> >>>> .section .note.GNU-stack,"",@progbits
> >>
> >>> Yes, this is against optimisations as you use volatile...
> >>
> >> I use volatile to prevent the compiler from optimizing away the
> >> function body.
> > Try more realistic example:
> > float read_val();
> > float process(int,float*);
> > float read_and_process(int n)
> > {
> > float vals[n];
> >
> > for (int i = 0; i < n; ++i)
> > vals[i] = read_val();
> >
> > return process(n, vals);
> > }
> >
> > Where is `leave` now?
> >
> The compiler will use it if it is convenient, and not use it
otherwise.
> This sample code /does/ generate "leave" with gcc :
> int f(int s )
> {
> int a[s];
> for (int i = 0; i < s; i++) a[i] = i;
> int t = 0;
> for (int i = 0; i < s; i++) t += a[i];
> return t;
> }
> (clang does not generate a "leave" - it generates its usual unrolled
> vector monstrosities that are highly efficient for huge loop
counts, and
> terrible for tiny counts.)
> Basically, it seems that "leave" is equivalent to "mov %ebp, %esp"
then
> "pop %ebp". If the compiler would otherwise have generated these
> instructions, then it uses "leave". If not, then it doesn't.
"leave"
> appears to be marginally more efficient than the separate
instructions -
> enough so to use it when there is the option, but not enough to go
out
> of its way to use it.
> (The matching "enter" instruction is much slower than manual
> manipulation of the registers, and is thus avoided.)
This is not reallistic example as well.
--
Press any key to continue or any other to quit
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-10-01 21:10 +0200 |
| Message-ID | <qn08bp$7n0$1@dont-email.me> |
| In reply to | #68856 |
On 01/10/2019 17:31, Bonita Montero wrote: >>> The compiler usually uses RPB to remember the frame-pointer-address >>> at the prolog of the function. EBP is more suitable because it can >>> be restored in one step by the x86 LEAVE-instruction. > >> So what? The RSP is restored automatically by the ret instruction. > > Yes, but LEAVE does three instructions in one step. Usually this > results in the same uOPs, but it is only one slot in the decoder. I don't know this case, but typically on modern cpus "complex" instructions like "leave" are slower than manual expanding the instructions using "pop", "ret", etc. The easiest way to find out is to do a test compile (godbolt.org is great for it) making sure you have cpu-specific tuning flags and optimisations enabled, and look at the output. The compiler writers know better than most of us which instruction patterns are the most efficient.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2019-10-01 21:25 +0200 |
| Message-ID | <qn096o$3qm$2@news.albasani.net> |
| In reply to | #68864 |
> I don't know this case, but typically on modern cpus "complex" > instructions like "leave" are slower than manual expanding the > instructions using "pop", "ret", etc. That's wrong.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-10-01 20:44 +0000 |
| Message-ID | <vUOkF.1997$9v2.1600@fx31.iad> |
| In reply to | #68868 |
Bonita Montero <Bonita.Montero@gmail.com> writes: >> I don't know this case, but typically on modern cpus "complex" >> instructions like "leave" are slower than manual expanding the >> instructions using "pop", "ret", etc. > >That's wrong. From the Intel optimization guide: The Intel 64 and IA-32 architectures have several commonly used instructions for parameter passing and procedure entry and exit: PUSH, POP, CALL, LEAVE and RET. These instructions implicitly update the stack pointer register (RSP), maintaining a combined control and parameter stack without software intervention. These instruc- tions are typically implemented by several ops in previous microarchitectures. The Stack Pointer Tracker moves all these implicit RSP updates to logic contained in the decoders themselves. The feature provides the following benefits: ˇ Improves decode bandwidth, as PUSH, POP and RET are single op instructions in Intel Core microarchitecture. ˇ Conserves execution bandwidth as the RSP updates do not compete for execution resources. ˇ Improves parallelism in the out of order execution engine as the implicit serial dependencies between ops are removed. ˇ Improves power efficiency as the RSP updates are carried out on small, dedicated hardware. Assembly/Compiler Coding Rule 31. (ML impact, M generality) Avoid using complex instructions (for example, enter, leave, or loop) that have more than four ľops and require multiple cycles to decode. Use sequences of simple instructions instead. Complex instructions may save architectural registers, but incur a penalty of 4 ľops to set up parameters for the microsequencer ROM.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-10-01 23:26 +0200 |
| Message-ID | <qn0gav$qnn$1@dont-email.me> |
| In reply to | #68868 |
On 01/10/2019 21:25, Bonita Montero wrote: >> I don't know this case, but typically on modern cpus "complex" >> instructions like "leave" are slower than manual expanding the >> instructions using "pop", "ret", etc. > > That's wrong. As a general point, I don't think it is wrong - but from your posting it looks like it does not apply in the case of "leave". At least, gcc uses it, which is a reasonable indicator that it is more efficient than separate instructions. A little googling suggests that the "enter" instruction is slower than the individual instructions, but that "leave" is quite fast. There are plenty of other legacy CISC instructions that are slower than breaking them apart into equivalent simpler instructions, such as the "LOOP" instructions. I'm sure x86 assembly experts could give you more. I've seen the same thing on other processors too. IIRC, on the 68060 the hardware integer division instruction was slower than a software division routine.
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2019-10-01 21:08 -0600 |
| Message-ID | <1br23vu9nn.fsf@pfeifferfamily.net> |
| In reply to | #68874 |
David Brown <david.brown@hesbynett.no> writes: > On 01/10/2019 21:25, Bonita Montero wrote: >>> I don't know this case, but typically on modern cpus "complex" >>> instructions like "leave" are slower than manual expanding the >>> instructions using "pop", "ret", etc. >> >> That's wrong. > > As a general point, I don't think it is wrong - but from your posting it > looks like it does not apply in the case of "leave". At least, gcc uses > it, which is a reasonable indicator that it is more efficient than > separate instructions. > > A little googling suggests that the "enter" instruction is slower than > the individual instructions, but that "leave" is quite fast. There are > plenty of other legacy CISC instructions that are slower than breaking > them apart into equivalent simpler instructions, such as the "LOOP" > instructions. I'm sure x86 assembly experts could give you more. > > I've seen the same thing on other processors too. IIRC, on the 68060 > the hardware integer division instruction was slower than a software > division routine. There was a time when it was true. I'd be pretty surprised if it still were.
[toc] | [prev] | [next] | [standalone]
Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6 Next page →
Back to top | Article view | comp.lang.c++
csiph-web