Skip to content
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

[SDK] Circular buffer tweaks + cpu pressure test #3349

Merged

Conversation

CodeBlanch
Copy link
Member

@CodeBlanch CodeBlanch commented Jun 7, 2022

Changes

Ran into a race/deadlock using logic similar to CircularBuffer on #3305. Added a test to verify everything is good with CircularBuffer. In doing so I made a few tweaks:

  • Use Volatile.Read & Volatile.Write so everything will work on 32bit processors.
  • Use Interlocked.Exchange to do atomic read + set to null in the reader.

Also threw in nullable annotations since I was in there.

@CodeBlanch CodeBlanch requested a review from a team June 7, 2022 18:55
@codecov
Copy link

codecov bot commented Jun 7, 2022

Codecov Report

Merging #3349 (fe3a40f) into main (2ab6281) will decrease coverage by 0.51%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3349      +/-   ##
==========================================
- Coverage   86.14%   85.63%   -0.52%     
==========================================
  Files         268      268              
  Lines        9448     9444       -4     
==========================================
- Hits         8139     8087      -52     
- Misses       1309     1357      +48     
Impacted Files Coverage Δ
src/OpenTelemetry/Internal/CircularBuffer.cs 89.18% <100.00%> (-1.06%) ⬇️
...entation/ExportClient/OtlpGrpcTraceExportClient.cs 50.00% <0.00%> (-28.58%) ⬇️
...ation.AspNet.TelemetryHttpModule/ActivityHelper.cs 56.14% <0.00%> (-28.08%) ⬇️
...xporter.OpenTelemetryProtocol/OtlpTraceExporter.cs 59.09% <0.00%> (-18.19%) ⬇️
src/OpenTelemetry.Api/Context/RuntimeContext.cs 75.75% <0.00%> (-15.16%) ⬇️
...emetry.Api/Context/AsyncLocalRuntimeContextSlot.cs 87.50% <0.00%> (-12.50%) ⬇️
....TelemetryHttpModule/AspNetTelemetryEventSource.cs 23.33% <0.00%> (-6.67%) ⬇️
...emetry.Api/Internal/OpenTelemetryApiEventSource.cs 76.47% <0.00%> (-5.89%) ⬇️
...lemetry/Internal/SelfDiagnosticsConfigRefresher.cs 86.53% <0.00%> (-5.77%) ⬇️
...metryProtocol/Implementation/ActivityExtensions.cs 91.20% <0.00%> (-3.30%) ⬇️
... and 1 more

@CodeBlanch
Copy link
Member Author

@reyang @cijothomas Unless I misread or confused myself, I think all the feedback is addressed and this is ready to go 🤣

@reyang
Copy link
Member

reyang commented Jun 8, 2022

@reyang @cijothomas Unless I misread or confused myself, I think all the feedback is addressed and this is ready to go 🤣

I need more time to review/test the change.


if (headSnapshot - tailSnapshot >= this.Capacity)
{
return false; // buffer is full
}

var head = Interlocked.CompareExchange(ref this.head, headSnapshot + 1, headSnapshot);
if (head != headSnapshot)
if (Interlocked.CompareExchange(ref this.head, headSnapshot + 1, headSnapshot) != headSnapshot)
{
continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be useful to add Spinwait.SpinOnce() here before continue?

Copy link
Member Author

Choose a reason for hiding this comment

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

Defer to @reyang on this one, but I don't think so. This thread isn't so much waiting on another thread to finish as it is learning that some other thread took the head. It should retry immediately and just take the next head/index available.

Copy link
Member

Choose a reason for hiding this comment

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

SpinOnce might be more smart yielding if singlecore etc?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think a yield here would be even worse than a spin 😄 Because it doesn't need to wait on anything. If there is only 1 core this thread should just loop around, take the next index, and continue on doing its thing. Same as if there were many cores, really.

There should probably be a SpinOnce here though:

Because that logic is actually waiting on the writer thread to finish. On single core, it should yield immediately because a spin won't accomplish anything other than delay letting the writer get the CPU back to finish its job 🤣

Copy link
Member

Choose a reason for hiding this comment

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

I think a yield here would be even worse than a spin

+1

Copy link
Member

@reyang reyang left a comment

Choose a reason for hiding this comment

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

LGTM.

@CodeBlanch CodeBlanch merged commit a80f1f2 into open-telemetry:main Jun 11, 2022
@CodeBlanch CodeBlanch deleted the circular-buffer-cpupressuretest branch June 11, 2022 00:10
alanwest added a commit that referenced this pull request Jun 27, 2022
* Added Jaeger Propagator to Opentelemetry.Extensions.Propagators (#3309)

* Remove unnecessary bullet in CHANGELOG.md (#3352)

Co-authored-by: Cijo Thomas <[email protected]>

* Fix OTLP test (#3357)

* Show that test is not doing what you might think it does

* More asserts the merrier

* Show this little test that it has potential

* improve test coverage: InMemoryExporter & IDeferredMeterProviderBuilder (#3345)

* [SDK] Circular buffer tweaks + cpu pressure test (#3349)

* CircularBuffer tweaks and cpu pressure test.

* Switch to Volatile.Read.

* Perf tweaks.

* Remove race check in debug after doing more testing.

Co-authored-by: Cijo Thomas <[email protected]>

* Fix event name logic + support null categoryname. (#3359)

* In-memory Exporter: Buffer log scopes (#3360)

* Buffer log scopes when using in-memory exporter.

* CHANGELOG update.

* Code review.

* Tests.

* CHANGELOG tweak.

* SDK: Forward SetParentProvider to children of CompositeProcessor (#3368)

* Examples: Fix ParentProvider not being set on MyFilteringProcessor (#3370)

* Fix ParentProvider not being set on MyFilteringProcessor example.

* Added XML comments.

* Tweak.

* Typo.

* Logs: Add helper ctors & forceflush on OpenTelemetryLoggerProvider (#3364)

* Add helper ctors & forceflush on OpenTelemetryLoggerProvider.

* CHANGELOG update.

* Unit tests.

* Code review.

* Code review.

* Tweak.

* SDK: Nullable annotations for base classes & batch + shims to enable compiler features (#3374)

* Nullable annotations and shims for SDK base classes & batch.

* Target updates.

* Remove System.Collections.Immutable ref.

* ApiCompat attribute exclusions.

* ASPNETCore instrumentation to populate httpflavor tag (#3372)

* improve test coverage: InMemoryExporter SnapshotMetric (#3344)

* Fix AspNetCore metrics to use correct value for http.flavor (#3379)

* Fix AspNetCore metrics to use correct value for http.flavor

* word better

* Logs: Add LogRecordData (#3378)

* Add LogRecordData and hook up to LogRecord.

* CHANGELOG update.

* Code review.

* Remove SetHttpFlavor from Http instrumentations (#3381)

* Asp.Net Core trace instrumentation to populate http schema tag (#3392)

* Try asp.net core tests with inproc server (#3394)

* Dedupe IsPackable (#3398)

* Remove AspNet and AspNet.TelemetryHttpModule instrumentation projects (#3397)

* Handle possible exception when initializing the default service name (#3405)

* HttpClient: Invoke Enrich when SocketException = HostNotFound (#3407)

* Add & use ConfigureResource API. (#3307)

Co-authored-by: tyler jago <[email protected]>
Co-authored-by: Robert Pająk <[email protected]>
Co-authored-by: Cijo Thomas <[email protected]>
Co-authored-by: Timothy Mothra <[email protected]>
Co-authored-by: Mikel Blanchard <[email protected]>
Co-authored-by: Reiley Yang <[email protected]>
Co-authored-by: Utkarsh Umesan Pillai <[email protected]>
Co-authored-by: Christian Neumüller <[email protected]>
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.

4 participants