-
Notifications
You must be signed in to change notification settings - Fork 1.1k
add a test to demonstrate #2546 #2548
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
Conversation
@0x53A apologies for not responding to this earlier, just been catching myself up on the issue now... So I think I understand the issue here: the Honestly, I agree with @Danthar's sentiment earlier that this is a TPL design issue, but none the less we should do something about it. Holding up Akka.Remote for however long the task runs isn't cool. Couple of ideas for things we can do without bumping to 4.6 (that's a bigger change:)
For now, we should log it and address it as "won't fix" (until we decide on bumping the .NET Framework version, which we have an opportunity to do coming up....) This can be remedied by not calling |
Hi @Aaronontheweb , thank you for taking a look at this. The FutureActorRef directly running on the DedicatedThreadPool is not the real problem, as it itself is fast.
For myself I have fixed it by reimplementing Ask in my own code, which targets net 4.6
The case with two Asks deadlocking is just an extreme case, where the issue becomes easily visible - anything executed after an await will still block the DedicatedThreadPool. So If I were to do something like
Then the ActorSystem would stop receiving messages for the duration of the CPU work. Or if I did
then it would block until I close the MessageBox. This only isn't an issue, if you do a second await directly afterwards, so that it thread switches again. I think there are two possible fixes while still compiling again 4.5:
I can think of no case, where the current behaviour is desireable, so I would go with option 2. |
9648a19
to
3f91e7f
Compare
@Aaronontheweb the current failures are Is the CI just slightly flaky, or did I break something? |
green, and Akka.Tests.Performance.dll passed between [23:27:45] and [23:52:40] which is 24:55 |
As it's currently implemented, this is not a good change. Performance numbers as measured by Before
---------------- |---------------- |---------------- |---------------- |---------------- |---------------- | Per-second Totals
---------------- |---------------- |---------------- |---------------- |---------------- |---------------- | AfterTotals
---------------- |---------------- |---------------- |---------------- |---------------- |---------------- | Per-second Totals
---------------- |---------------- |---------------- |---------------- |---------------- |---------------- | It's the number of allocations that's the concern here. It's the I'm reluctant to implement this change anyway because it's a hack for an edge case that hasn't been reported in 3 years. I'd rather fix it correctly by fixing or eliminating our usage of |
The thing is, this is NOT related to await, this is related to This probably didn't surface before because in most usage cases the I will try how much performance using a static method would recoup, and I will also test it with RunContinuationsAsynchronously. I assume that RunContinuationsAsynchronously would also be worse than the baseline, because internally it would need to schedule the continuations on the threadpool anyway. If you say you won't pull this because of the performance, then I can totally understand that and feel free to close it. I have reimplemented Ask for myself, so am not blocked by this. But even though it may be an edge case, if you hit it, it is a) hard to find out the root cause and b) impossible to work around externally without reimplementing Ask. |
@0x53A there'd be a performance hit on any continuations that occur after the original |
@Aaronontheweb I think most users will actually run on >= net 4.6, regardless of what Akka is compiled against. What would you think about checking at runtime if we can use This is not perfect, because then changing the runtime would change the execution in a subtle way. Edit: I found a really good explanation of the issue here: http://stackoverflow.com/questions/22579206/how-can-i-prevent-synchronous-continuations-on-a-task |
This is the result of DEV vs RunContinuationsAsynchronously: BASELINE Akka.Tests.Performance.Actor.Pattern.AskSpec+AskThroughputTests how quickly ICanTell.Ask operations can be performed, and with how much memory System InfoNBench=NBench, Version=0.3.4.0, Culture=neutral, PublicKeyToken=null
OS=Microsoft Windows NT 6.2.9200.0
ProcessorCount=8
CLR=4.0.30319.42000,IsMono=False,MaxGcGeneration=2
WorkerThreads=32767, IOThreads=8 NBench SettingsRunMode=Throughput, TestMode=Measurement
NumberOfIterations=3, MaximumRunTime=00:00:05
Concurrent=True
Tracing=True DataTotals
Per-second Totals
Raw DataTotalBytesAllocated
[Counter] AskReplies
with RunContinuationsAsynchronously Akka.Tests.Performance.Actor.Pattern.AskSpec+AskThroughputTests how quickly ICanTell.Ask operations can be performed, and with how much memory System InfoNBench=NBench, Version=0.3.4.0, Culture=neutral, PublicKeyToken=null
OS=Microsoft Windows NT 6.2.9200.0
ProcessorCount=8
CLR=4.0.30319.42000,IsMono=False,MaxGcGeneration=2
WorkerThreads=32767, IOThreads=8 NBench SettingsRunMode=Throughput, TestMode=Measurement
NumberOfIterations=3, MaximumRunTime=00:00:05
Concurrent=True
Tracing=True DataTotals
Per-second Totals
Raw DataTotalBytesAllocated
[Counter] AskReplies
Even this seems to have a pretty drastic perfomance impact:
So if that is the best the BCL team managed, then I don't think I will be able to find a way to solve this issue without performance impacts. |
I would propose to take advantage of This would still have a small performance impact, but especially the bytes/op seem to be a bit better. Edit: I added my proposed changes here: #3120 Would be interesting to see if there are any performance differences (and how large). |
Pulling the data from the CI server: (TR=Task.Run, RCA=RunContinuationsAsynchronously )
|
Just noticed #3120. Closing this one |
This one was superseded by the other one. With the other one it uses RCA if available (if the user is running on net46) and otherwise falls back to task.run. This should (slightly) improve performance, especially allocations. |
Got it. |
ref #2546