Skip to content

optimize state machine inside loop into computed goto #2162

Closed as not planned

Description

@andrewrk

Related issues:

One remaining use case for computed goto is performance. This pattern:

const State = enum {
    one,
    two,
};
while (true) {
    switch (state) {
        .one => {
            state = .two;
        },
        .two => {
            // ...
        },
    }
}

Here the code relies on setting the state variable and a loop iteration. In C the code could directly goto another switch label. In Zig this is not available, and the code generated is worse than in C due to the optimizer's inability to detect this pattern.

Upstream bug, reported by @shawnl: https://bugs.llvm.org/show_bug.cgi?id=39043

Potential solutions include:

  • (ideal) send upstream patch to LLVM making it able to detect this pattern and optimize it. It seems reasonable that this should work, given that both gcc and icc are able to do it.
  • make zig detect this pattern and emit different LLVM IR

I don't consider this to be blocking a 1.0.0 release.

Activity

  1. added
    contributor friendlyThis issue is limited in scope and/or knowledge of Zig internals.
    upstreamAn issue with a third party project that Zig uses.
    on Apr 1, 2019
  2. added this to the 1.1.0 milestone on Apr 1, 2019
  3. PavelVozenilek commented on Apr 2, 2019

    @PavelVozenilek

    Performance of computed goto highly depends on processor and the task. It is not always faster then the ordinary switch.

    Perhaps the compiler should be given a hint in form of designated tests. Depending on timing of these tests, it would then pick up the best performing implementation.

    This topic gets sometimes discussed on Forth forums, they found that the old truths are not absolute, as they once were.

  4. shawnl commented on Apr 2, 2019

    @shawnl
    Contributor

    @PavelVozenilek
    There are times where a state only leads to an error condition, or to the next state, however, and clang is incapable of in-lining these cases.

  5. andrewrk commented on Apr 2, 2019

    @andrewrk
    MemberAuthor

    Perhaps the compiler should be given a hint in form of designated tests. Depending on timing of these tests, it would then pick up the best performing implementation.

    Profile guided optimization is #237

  6. tgschultz commented on Apr 2, 2019

    @tgschultz
    Contributor

    I personally am not a fan of having to rely on the optimizer to do the right thing, and then trying to fool it into doing the right thing when it doesn't. While allowing the compiler to make this optimization is a good idea, I feel that that is not sufficient to cover the computed goto use case and some explicit mechanism should still be available.

  7. PavelVozenilek commented on Apr 2, 2019

    @PavelVozenilek

    @shawnl: as I understand it, computed goto performance advantage depends on ability of the processor to predict which code path would be executed next (and start speculative execution of this path in advance). With one big switch such prediction is not feasible.

    In Forth interpreter code paths are few and short, and common patterns of code are frequent. The processor prediction could then make a big difference.

    I do not see how inlining could play a role here, but could be easily wrong.

  8. shawnl commented on Jun 20, 2020

    @shawnl
    Contributor

    A good benchmark for this issue would be a re2c lexer.

  9. andrewrk commented on Oct 1, 2023

    @andrewrk
    MemberAuthor

    Closing in favor of #8220

  10. modified the milestones: 1.1.0, 0.12.0 on Oct 13, 2023
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

    contributor friendlyThis issue is limited in scope and/or knowledge of Zig internals.optimizationupstreamAn issue with a third party project that Zig uses.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions