Advertisement
theosib

Untitled

Nov 28th, 2017
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.22 KB | None | 0 0
  1. Hi, everyone,
  2.  
  3. I have been working for nearly a month, in most of my spare time, on finding ways to improve the performance and undesirable behaviors of redstone wire. Depowering can be especially compute-intensive, and update order is both random and nondeterministic due to HashSet behavior. I have focused my attention on the execution critical path for computing new wire power levels and propagating them to neighbors, and I have found many inefficiencies whose mitigation would improve Minecraft performance across the board. For instance, there are multiple methods in World that compute the 6 cardinal neighbors of a given block position. During redstone wire depowering, the neighbors of the same positions are recomputed over and over again. BlockPos objects are immutable, so repeating the same work introduces wastes a great deal of time, and I found a simple caching mechanism to yield a significant performance boost. However, since this and other such global optimizations are not specific to redstone wire, I will not be presenting them here.
  4.  
  5. Before I continue, I realize that the developers are very busy with the 1.13 snapshot. However, it is during snapshot periods that instabilities and behavioral changes are expected, making this an ideal opportunity to identify any undesirable effects. Moreover, this is also an opportunity for developers to offer an olive branch to the technical community, addressing two problems that affect them severely, serious lag and inconsistent behavior.
  6.  
  7. Some time ago, our esteemed friend Panda4994 uploaded an improved implementation of BlockRedStoneWire. I skimmed quickly over his code, and I had also read a great deal of the comments on this bug report, albeit a very long time ago, so some statements below may be inaccurate. From what I can gather, the reasons that Mojang declined to implement Panda's improvements include the following:
  8.  
  9. - It affected code outside of BlockRedstoneWire and/or replicated code from elsewhere in Minecraft.
  10. - Concerns were raised about changes to block update order breaking existing redstone contraptions.
  11. - It's a ground-up rewrite of BlockRedstoneWire, which would require too much developer time to analyze and reimplement in the real Minecraft code.
  12. - Something about it being "messy," although I'm not sure what that's supposed to mean.
  13.  
  14. While I would not be at all surprised if Panda's implementation outperformed mine, I have set out to develop an accelerator for redstone wire that is more likely to be adopted because it addresses each of the above concerns, as follows:
  15.  
  16. - No Minecraft code outside of BlockRedstoneWire is affected by this accelerator.
  17. - Changes to BlockRedstoneWire are minimal.
  18. - The bulk of the new functionality is implemented in a new helper class, making it straightforward to drop the new code into Minecraft with negligible refactoring.
  19. - The helper code is carefully written, with copious commenting in order to make its operation as clear as possible.
  20.  
  21. You can think of this accelerator code as being analogous to a bolt-on after-market supercharger that is designed for minimal installation effort. (Despite the fact that I used the word 'Turbo' in the class name, I do know the difference between a supercharger and a turbocharger. 'Turbo' sounds cooler and uses fewer letters.)
  22.  
  23. You can find the new code in the file "RedstoneWireTurbo.zip" attached to this bug report. Inside, you will find the following files:
  24.  
  25. - BlockRedstoneWire.java -- Updated version of BlockRedstoneWire that implements the 45% performance improvement I posted about earlier and hooks into the helper class that contains the optimized redstone wire code.
  26. - BlockRedstoneWire.diff -- The differences between the vanilla BlockRedstoneWire code (from MCP for 1.12.2) and the modified version.
  27. - RedstoneWireTurbo.java -- Helper class that implements the improved and performance-optimized redstone wire update algorithm.
  28.  
  29. Main features of this redstone wire performance accelerator include the following:
  30.  
  31. - As stated above, changes to BlockRedstoneWire are very limited and no other classes are affected.
  32. - The choice between old and new redstone wire update algorithms is switchable on-line.
  33. - The unmodified Minecraft code relies on World.notifyNeighborsOfStateChange for redstone wire blocks to communicate power level changes to each other, generating 36 block updates per call. This optimized implementation propagates power level changes directly between redstone wire blocks. Redstone wire power levels are therefore computed more quickly. Since redstone power level states are computed internally, no block updates are necessary from redstone wire to redstone wire. Block updates are sent only to non-redstone blocks, many of which may perform an action when informed of a change in redstone power level.
  34. - Of the 36 block updates generated by a call to World.notifyNeighborsOfStateChange, 12 of them are obviously redundant (e.g. the west neighbor of the east neighbor). These are eliminated.
  35. - Updates to redstone wire and other connected blocks are propagated in a breath-first manner, radiating out from the initial trigger (a block update to a redstone wire from something other than redstone wire).
  36. - Block updates are scheduled both deterministically and in an intuitive order. **This addresses bug MC-11193.**
  37. - All redstone behavior that used to be locational now works the same in all locations.
  38. - A few behaviors still depend on orientation; for instance, west is processed before east.
  39. - Information that is otherwise computed over and over again or which is expensive to to compute is cached internally for faster lookup. This includes coordinates of block position neighbors and block states that won't change behind our backs during the execution of the search algorithm.
  40. - Redundant block updates (both to redstone wire and to other blocks) are heavily consolidated. For worst-case scenarios (depowering of redstone wire) this results in a reduction of block updates by as much as 95% (factor of 1/21). Due to overheads, empirical testing shows a speedup better than 6x. **This addresses bug MC-81098.**
  41.  
  42. Extensive testing has been performed to ensure that existing redstone contraptions still behave as expected. Results of early testing that had identified undesirable behavior changes were addressed. Additionally, real-time performance testing revealed compute inefficiencies with earlier implementations of this accelerator. Some compatibility adjustments and performance optimizations resulted in harmless increases in block updates above the theoretical minimum. That being said, 1.13 already introduces some important changes to redstone behavior. For instance, observer and comparator update priority have been reversed, which risks breaking many redstone designs that rely on specific within-tick update orders. Any changes to update order caused by my accelerator are likely to have less impact.
  43.  
  44. This redstone accelerator was first implemented on my testing server and has now also been added to carpet mod. The consensus of the testers (which include moderators from Mojira, members of SciCraft and ProtoTech, and other experts in redstone design) is that the changes are a distinct improvement over the current implementation. Observations include:
  45.  
  46. - Block updates that used to be random and nondeterministic all now make sense.
  47. - The activation of other redstone components now follows an order that is strictly a function distance from the input signal.
  48. - Some machines that used to work or not work depending on location now work the same regardless of location.
  49. - Zero-tick behaviors are preserved and are now 100% reliable regardless of position and orientation.
  50. - Numerous complex test cases were built, none of which showed any breakages (with one caveat, explained below), and the only changes observed were some really behaviors that made no sense before are eliminated, replaced by reliable, deterministic, intuitive behavior.
  51.  
  52. The only "breakage" that remains is one found by ilmango. To get an instant dropper line, there is this weird hack involving powered and activator rails and quasiconnectivity. This trick wasn't completely reliable, though, sometimes breaking depending on position or orientation. With the optimized redstone code, it no longer works at all. HOWEVER, with the optimizations, all you have to do to get an instant dropper line is to lay redstone wire on top of a line of droppers and power the wire at the input end of the dropper line. Where this previously did not work in all orientations, it now world 100% reliably in ALL orientations. This includes vertical (where you spiral blocks and redstone wire up or down around the droppers).
  53.  
  54. As I mentioned above, there are many other optimizations that can be made, but most of them can be implemented independently and will synergize with this one.
  55.  
  56. I have the following individuals and more to thank for their help in testing this new code:
  57.  
  58. - pokechu22 (Mojira)
  59. - _MethodZz_ (SciCraft)
  60. - WARBEN
  61. - NarcolepticFrog (ProtoTech and SciCraft)
  62. - CommandHelper, aka nessie (ProtoTech)
  63. - ilmango (SciCraft)
  64. - OreoLamp
  65. - Xcom6000 (SciCraft)
  66. - tryashtar (Mojira)
  67. - RedCMD
  68. - Smokey95Dog (ProtoTech)
  69. - EDDxample
  70. - Rays Works (ProtoTech)
  71. - Nodnam
  72. - BlockyPlays (FrostCraft)
  73. - TT (Dugged), for his jungle tree farm
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement