Skip to content

Minor yield() cleanup: optimistic_yield, proper polledTimeout use #6869

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 19, 2021

Conversation

dok-net
Copy link
Contributor

@dok-net dok-net commented Dec 2, 2019

Suggest by @devyte, this PR attempts to point out and refactor those places in cores and libraries that appear to be calling yield() more often than needed, which would hurt performance.
Please review carefully.

@dok-net dok-net force-pushed the refactooptimisticyield branch from cb02120 to 3bc7d7d Compare December 2, 2019 16:20
@dok-net dok-net force-pushed the refactooptimisticyield branch from 3bc7d7d to d1e490c Compare December 11, 2019 13:44
@dok-net dok-net force-pushed the refactooptimisticyield branch from d1e490c to 6345e0a Compare January 18, 2020 15:28
@dok-net dok-net force-pushed the refactooptimisticyield branch 4 times, most recently from ef9ed97 to d6d49f2 Compare February 5, 2020 13:33
Copy link
Collaborator

@earlephilhower earlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally seems good, but I do have a style concern.

It seems to me that instead of putting in a hardcoded 10000 everywhere, a constexpr int maxyield = 10000; (or whatever name) in a header set to that would be more maintainable. I'm not fully sure there the 10ms came from or that it is the "right" number for all SDKs. Factoring it to a const that's in one place would be a much safer bet IMHO...

@dok-net dok-net force-pushed the refactooptimisticyield branch from 9a3d0da to 8ccc347 Compare March 1, 2020 10:23
@dok-net dok-net requested review from earlephilhower and devyte March 4, 2020 13:47
Copy link
Collaborator

@earlephilhower earlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assumption of this PR is that calling yield() hurts performance.

However, this is not a multitasking system and if there's no WIFI to service or timer callbacks, a yield is almost a call-and-immediate-return. Yes, it's not instantaneous, but the chip is not going to go off and try to do something else unless there's really other work to be done.

This PR is about performance, but the changes done here are not in performance critical sections. Debug printing hex values, switching APs off and then on again, etc. If it was inside a loop run 1,000 times or something, sure, but these changes are not like that.

Removing forced yield() can change behavior. Before if I put a message into a queue that would be serviced by the OS, the yield() would ensure that queue was pumped by the OS. Optimistic_yield() means that in most cases the queue won't be pumped (unless it's been 10ms already).

So in general, I'm not seeing this as helping things in an appreciable way while introducing changes which might cause instability or non-repeatable behavior.

@dok-net dok-net force-pushed the refactooptimisticyield branch from 8ccc347 to 97624b2 Compare March 8, 2020 18:28
@dok-net dok-net requested a review from earlephilhower March 8, 2020 18:28
@dok-net dok-net force-pushed the refactooptimisticyield branch from 97624b2 to 32c0a8e Compare April 9, 2020 22:09
@dok-net dok-net force-pushed the refactooptimisticyield branch from 32c0a8e to 7fe6e99 Compare May 2, 2020 00:59
@dok-net dok-net force-pushed the refactooptimisticyield branch from 7fe6e99 to 33154a9 Compare July 16, 2020 10:51
@dok-net dok-net force-pushed the refactooptimisticyield branch from 33154a9 to 63be40d Compare October 22, 2020 15:53
@dok-net dok-net force-pushed the refactooptimisticyield branch 3 times, most recently from a79f768 to f9c0a56 Compare December 30, 2020 15:29
@dok-net dok-net force-pushed the refactooptimisticyield branch from f9c0a56 to 61e5c6b Compare January 28, 2021 20:37
@dok-net dok-net force-pushed the refactooptimisticyield branch 2 times, most recently from 14513dd to 76deff8 Compare March 15, 2021 10:48
@dok-net dok-net force-pushed the refactooptimisticyield branch from 76deff8 to c06f208 Compare April 3, 2021 08:49
@dok-net dok-net force-pushed the refactooptimisticyield branch from c06f208 to d8369ae Compare April 28, 2021 12:30
@dok-net dok-net force-pushed the refactooptimisticyield branch from d8369ae to 6578f1e Compare May 16, 2021 10:26
@dok-net dok-net force-pushed the refactooptimisticyield branch from 6578f1e to 7571c72 Compare May 18, 2021 13:43
@dok-net dok-net changed the title Code smells: forced yield() hurts performance Minor yield() cleanup: optimistic_yield, proper polledTimeout use May 18, 2021
@dok-net
Copy link
Contributor Author

dok-net commented May 18, 2021

A reply to the performance remark you made, @earlephilhower.
This sketch indicates otherwise, I think:

void setup()
{
    Serial.begin(74880);
    delay(500);
    Serial.println("opty");
    pinMode(BUILTIN_LED, OUTPUT);
    digitalWrite(BUILTIN_LED, HIGH);
}

void loop()
{
    auto ts = ESP.getCycleCount();
    for (int i = 0; i < 1000000; ++i)
    {
        digitalWrite(BUILTIN_LED, LOW);
        yield();
        digitalWrite(BUILTIN_LED, HIGH);
    }
    auto ts2 = ESP.getCycleCount();
    Serial.print("1E6 iterations over yield, ms = ");
    Serial.println((ts2 - ts) / ESP.getCpuFreqMHz() / 1000);

    ts = ESP.getCycleCount();
    for (int i = 0; i < 1000000; ++i)
    {
        digitalWrite(BUILTIN_LED, LOW);
        optimistic_yield(10000);
        digitalWrite(BUILTIN_LED, HIGH);
    }
    ts2 = ESP.getCycleCount();
    Serial.print("1E6 iterations over optimistic_yield(10000), ms = ");
    Serial.println((ts2 - ts) / ESP.getCpuFreqMHz() / 1000);
}

Result:

1E6 iterations over yield, ms = 8660
1E6 iterations over optimistic_yield(10000), ms = 2554
1E6 iterations over yield, ms = 8660
1E6 iterations over optimistic_yield(10000), ms = 2554

@earlephilhower
Copy link
Collaborator

Thanks for the actual performance numbers!

Copy link
Collaborator

@earlephilhower earlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, seems like a very minor change with not much impact except in, say, hexdump().

@devyte devyte merged commit d7d03f9 into esp8266:master May 19, 2021
@dok-net dok-net deleted the refactooptimisticyield branch May 19, 2021 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants