microsoft / microsoft/STL

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

Open
#496 15 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

chrono performance vNext
Dominant language
C++
Stars
11.2k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read the Windows x64 calling-convention specification and the reproduction in the issue first, then review #169 for the vNext constraint. A complete resolution would require an agreed STL or ABI change and a way to validate the generated assembly; no repository file or test is identified.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
performance
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.