Skip to content

<chrono>: Windows x64 ABI: bad performance with wrapped data like chrono::seconds #496

Description

I observed that if I return for example a std::chrono::seconds object from a not inlined method / function my code becomes 5 times slower compared to direct usage of long long (x64 compilation on Windows).

The reason for this is the Windows x64 ABI. See:
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019

According to this spec each value (which has a base class or custom constructor) is returned via stack and not via using a register. I would really like to use these wrapped data structures and others. But I can't accept such a big performance hit.

Is there any way to explicitly tell the compiler to return such simple values via register (exactly like the underlying data)?

To reproduce the issue I show you some simple code:

__declspec(noinline)
std::chrono::seconds Foo() {
    return std::chrono::seconds{ 42 };
}

__declspec(noinline)
long long Foo2() {
    return 42;
}

int main()
{
    auto f = Foo();
    auto f2 = Foo2();
    std::cout << "Hello World!\n" << *reinterpret_cast<long long*>(&f) << f2;
}

The code results in the following assembly:

Foo:

00007FF737C31000  mov         qword ptr [rcx],2Ah  
00007FF737C31007  mov         rax,rcx

Instead of Foo2:

00007FF737C31010  mov         eax,2Ah

For my project I use only a single compiler and don't care ABI compatibility across compilers.

vNext note: Resolving this issue will require breaking binary compatibility. We won't be able to accept pull requests for this issue until the vNext branch is available. See #169 for more information.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    chronoC++20 chronoperformanceMust go fastervNextBreaks binary compatibility

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions