Thread overview
are MRV as an optimization well known ?
Dec 28, 2015
Basile B.
Dec 28, 2015
Basile B.
Dec 28, 2015
Basile B.
December 28, 2015
While working on a framework, I've found that Multiple Return Values (MRV) are clearly an optimization. I'de like to write a small D blog post about this but I don't know If it's clever enough or if it's a well know fact.

My base D material is this:

---
#!runnable-flags: -O -boundscheck=off -release
module runnable;

struct Get
{
    static auto all()
    {
        import std.typecons;
        return tuple(0.1f,0.2f,0.3f,0.4f);
    }
    static float a(){return 0.1f;}
    static float b(){return 0.2f;}
    static float c(){return 0.3f;}
    static float d(){return 0.4f;}
}

void call(float a, float b, float c, float d){}

void tupYes()
{
    call(Get.all[0..$]);
}

void tupNo()
{
    call(Get.a, Get.b, Get.c, Get.d);
}

void main(string[] args)
{
    import disassembler;
    import std.stdio;

    symbolTable.addModule!runnable;
    writeln(prettyDisasm(&tupYes));
    writeln;
    writeln(prettyDisasm(&tupNo));
}
---

with my d beaengine bindings I get this (bin comes from DMD backend) :

;------- SUB 000000000044C918h -------
; NAMED: tupYes
000000000044C918h  push rbp
000000000044C919h  mov rbp, rsp
000000000044C91Ch  sub rsp, 20h
000000000044C920h  call 0044C8A0h
000000000044C925h  movsd qword ptr [rbp-20h], xmm0
000000000044C92Ah  fld qword ptr [rbp-20h]
000000000044C92Dh  movsd qword ptr [rbp-20h], xmm1
000000000044C932h  fld qword ptr [rbp-20h]
000000000044C935h  fstp qword ptr [rbp-08h]
000000000044C938h  fstp qword ptr [rbp-10h]
000000000044C93Bh  movss xmm3, dword ptr [rbp-10h]
000000000044C940h  movss xmm2, dword ptr [rbp-0Ch]
000000000044C945h  movss xmm1, dword ptr [rbp-08h]
000000000044C94Ah  movss xmm0, dword ptr [rbp-04h]
000000000044C94Fh  call 0044C910h ; (call)
000000000044C954h  mov rsp, rbp
000000000044C957h  pop rbp
000000000044C958h  ret
;-------------------------------------

;------- SUB 000000000044C960h -------
; NAMED: tupNo
000000000044C960h  sub rsp, 78h
000000000044C964h  call 0044C8D0h
000000000044C969h  movss dword ptr [rsp], xmm0
000000000044C96Eh  movss xmm3, dword ptr [rsp]
000000000044C973h  movapd dqword ptr [rsp+10h], xmm3
000000000044C979h  call 0044C8E0h
000000000044C97Eh  movss dword ptr [rsp], xmm0
000000000044C983h  movss xmm2, dword ptr [rsp]
000000000044C988h  movapd xmm3, dqword ptr [rsp+10h]
000000000044C98Eh  movapd dqword ptr [rsp+20h], xmm2
000000000044C994h  movapd dqword ptr [rsp+30h], xmm3
000000000044C99Ah  call 0044C8F0h
000000000044C99Fh  movss dword ptr [rsp], xmm0
000000000044C9A4h  movss xmm1, dword ptr [rsp]
000000000044C9A9h  movapd xmm2, dqword ptr [rsp+20h]
000000000044C9AFh  movapd xmm3, dqword ptr [rsp+30h]
000000000044C9B5h  movapd dqword ptr [rsp+40h], xmm1
000000000044C9BBh  movapd dqword ptr [rsp+50h], xmm2
000000000044C9C1h  movapd dqword ptr [rsp+60h], xmm3
000000000044C9C7h  call 0044C900h
000000000044C9CCh  movapd xmm1, dqword ptr [rsp+40h]
000000000044C9D2h  movapd xmm2, dqword ptr [rsp+50h]
000000000044C9D8h  movapd xmm3, dqword ptr [rsp+60h]
000000000044C9DEh  call 0044C910h ; (call)
000000000044C9E3h  add rsp, 78h
000000000044C9E7h  ret
;-------------------------------------

Which clearly shows that using the MRV version is faster than grabing each property, since in the second, version there's a call for each parameter.

When I google "MRV optimization tuple", there's nothing, maybe some garbages from the early 2000's...nothing else. I'd like your mind before writing something possibly ridiculous.
December 28, 2015
I mean it's maybe "just" a special case of RVO, since tuples are processed as structs ?


December 28, 2015
On Monday, 28 December 2015 at 12:40:09 UTC, Basile B. wrote:
> I mean it's maybe "just" a special case of RVO, since tuples are processed as structs ?

Also in the second version the stack size is modified by 78 bytes. Not when using MRV.