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

Shrink Entity Struct #64

Closed
5 tasks done
caibear opened this issue May 20, 2021 · 10 comments
Closed
5 tasks done

Shrink Entity Struct #64

caibear opened this issue May 20, 2021 · 10 comments
Labels
performance Performance related server Only related to the server

Comments

@caibear
Copy link
Member

caibear commented May 20, 2021

For the possibility of performance we can shrink the world.Entity struct to 32 bytes from 64 bytes (1/2 the size and still power of 2).
The point of this issue is to discuss if we should implement this to test it or if the cons would outweigh any estimated pros.

// The current struct (64 bytes):
type Entity struct {
	Transform                // 16 bytes (8 bytes pos + 4 bytes vel + 4 bytes dir)
	Guidance                 // 8 bytes (4 bytes vel + 4 bytes dir)
	EntityType               // 1 byte (eventually may be 2 bytes once entity count > 255)
	Damage   float32         // 4 bytes
	Distance float32         // 4 bytes
	Lifespan float32         // 4 bytes
	Owner    *Player         // 8 bytes
	ext      unsafeExtension // 8 bytes
        // EntityID EntityID     // 4 bytes
        // _ [4]byte             // 4 bytes struct padding
}

Required changes:

  • Convert world.Angle from float32 to uint16 with 0 meaning 0.0 and 65535 being 2 Pi * 65535 / 65536.
  • Move world.Extension (unsafeExtension) to world.Player.
  • Move Entity.Damage to world.Extension.
  • Remove Entity.Distance as it can be estimated from lifespan.
  • Change lifespan and velocity(Target) to uint16 and int16 (Lifespan measured in 100/ms increments).
// The new struct (32 bytes):
type Entity struct {
	Transform                // 12 bytes (8 bytes pos + 2 bytes vel + 2 bytes dir)
	Guidance                 // 4 bytes (2 bytes vel + 2 bytes dir)
        Owner    *Player         // 8 bytes
	EntityType               // 1 byte (eventually may be 2 bytes once entity count > 255)
	Lifespan uint16          // 2 bytes
        // EntityID EntityID     // 4 bytes
}

Possible Pros:

  • Entities use 1/2 the memory.
  • Better locality of reference for iterating entities (speculating ~5-10% performance improvement of world functions from previous optimization).
    *Angles can be added/subtracted together without expensive math32.Mod.
  • Allows us to do further optimizations with less copying like AOS vs SOA.

Cons:

  • Player can't have more than 1 boat in the future (unless we make []Extension).
  • More complex math and marshaling for angles, velocities, and lifespans.
  • Entity.Distance() is just an estimate and may not be accurate.
  • If we want to add more fields we will need to be more creative in the future.

Note that this is just an idea and may not be worth the added complexity.

@caibear caibear added the performance Performance related label May 20, 2021
@caibear caibear mentioned this issue May 20, 2021
15 tasks
@finnbear
Copy link
Member

How can the difference between two angles be calculated if negative angles cannot be represented?

@caibear
Copy link
Member Author

caibear commented May 21, 2021

You can just convert the angle to an int16 when you want to have that representation.

@caibear
Copy link
Member Author

caibear commented May 21, 2021

Angle has been converted to uint16 completing one of the requirements.

@caibear caibear added the server Only related to the server label May 21, 2021
@caibear
Copy link
Member Author

caibear commented May 21, 2021

Velocity has been converted to int16 completing another one of the requirements.

@caibear
Copy link
Member Author

caibear commented May 21, 2021

Entity.Distance has been removed completing another one of the requirements.

@caibear
Copy link
Member Author

caibear commented May 22, 2021

Once #69 is merged lifespan will be uint16. There are only 2 more requirements left.

@caibear
Copy link
Member Author

caibear commented May 22, 2021

Damage has been moved.

@caibear
Copy link
Member Author

caibear commented May 22, 2021

Moved extension to Player.

@caibear
Copy link
Member Author

caibear commented May 22, 2021

Benchmark Comparison on my computer:

benchmark                                         old ns/op     new ns/op     delta
BenchmarkSectorWorld/EntityByID/64-12             219           225           +2.69%
BenchmarkSectorWorld/EntityByID/256-12            221           225           +1.76%
BenchmarkSectorWorld/EntityByID/1024-12           234           231           -1.41%
BenchmarkSectorWorld/EntityByID/4096-12           269           256           -4.90%
BenchmarkSectorWorld/EntityByID/16384-12          297           288           -2.86%
BenchmarkSectorWorld/EntityByID/65536-12          346           331           -4.20%
BenchmarkSectorWorld/InRadius/64-12               224           220           -1.52%
BenchmarkSectorWorld/InRadius/256-12              251           249           -0.80%
BenchmarkSectorWorld/InRadius/1024-12             351           342           -2.40%
BenchmarkSectorWorld/InRadius/4096-12             356           352           -1.10%
BenchmarkSectorWorld/InRadius/16384-12            371           360           -2.83%
BenchmarkSectorWorld/InRadius/65536-12            371           367           -1.08%
BenchmarkSectorWorld/Iterate/64-12                28.0          27.5          -1.93%
BenchmarkSectorWorld/Iterate/256-12               26.4          25.5          -3.52%
BenchmarkSectorWorld/Iterate/1024-12              26.1          26.2          +0.38%
BenchmarkSectorWorld/Iterate/4096-12              27.6          25.4          -8.11%
BenchmarkSectorWorld/Iterate/16384-12             27.1          26.5          -2.40%
BenchmarkSectorWorld/Iterate/65536-12             28.8          27.6          -3.86%
BenchmarkSectorWorld/IterateParallel/64-12        165           165           -0.06%
BenchmarkSectorWorld/IterateParallel/256-12       55.4          53.4          -3.56%
BenchmarkSectorWorld/IterateParallel/1024-12      23.3          22.3          -4.33%
BenchmarkSectorWorld/IterateParallel/4096-12      11.5          10.7          -6.86%
BenchmarkSectorWorld/IterateParallel/16384-12     6.53          6.04          -7.47%
BenchmarkSectorWorld/IterateParallel/65536-12     4.72          4.37          -7.43%
BenchmarkSectorWorld/IterateRadius/64-12          302           276           -8.70%
BenchmarkSectorWorld/IterateRadius/256-12         341           305           -10.53%
BenchmarkSectorWorld/IterateRadius/1024-12        439           417           -4.99%
BenchmarkSectorWorld/IterateRadius/4096-12        441           418           -5.19%
BenchmarkSectorWorld/IterateRadius/16384-12       454           431           -5.15%
BenchmarkSectorWorld/IterateRadius/65536-12       460           436           -5.35%

@finnbear
Copy link
Member

benchmark                                        old ns/op     new ns/op     delta
BenchmarkSectorWorld/EntityByID/64-8             57.9          55.9          -3.56%
BenchmarkSectorWorld/EntityByID/256-8            66.1          55.3          -16.41%
BenchmarkSectorWorld/EntityByID/1024-8           59.4          56.9          -4.36%
BenchmarkSectorWorld/EntityByID/4096-8           65.0          62.4          -4.09%
BenchmarkSectorWorld/EntityByID/16384-8          73.3          71.1          -3.02%
BenchmarkSectorWorld/EntityByID/65536-8          120           90.2          -25.18%
BenchmarkSectorWorld/InRadius/64-8               57.8          58.2          +0.76%
BenchmarkSectorWorld/InRadius/256-8              66.4          66.1          -0.35%
BenchmarkSectorWorld/InRadius/1024-8             90.0          91.2          +1.27%
BenchmarkSectorWorld/InRadius/4096-8             93.3          94.3          +1.09%
BenchmarkSectorWorld/InRadius/16384-8            95.7          98.1          +2.50%
BenchmarkSectorWorld/InRadius/65536-8            99.9          100           +0.09%
BenchmarkSectorWorld/Iterate/64-8                6.99          6.82          -2.43%
BenchmarkSectorWorld/Iterate/256-8               6.59          6.31          -4.25%
BenchmarkSectorWorld/Iterate/1024-8              6.69          6.26          -6.34%
BenchmarkSectorWorld/Iterate/4096-8              6.73          6.68          -0.70%
BenchmarkSectorWorld/Iterate/16384-8             6.80          6.62          -2.69%
BenchmarkSectorWorld/Iterate/65536-8             8.67          6.95          -19.87%
BenchmarkSectorWorld/IterateParallel/64-8        27.0          27.1          +0.52%
BenchmarkSectorWorld/IterateParallel/256-8       10.5          10.0          -5.03%
BenchmarkSectorWorld/IterateParallel/1024-8      5.97          5.49          -8.08%
BenchmarkSectorWorld/IterateParallel/4096-8      3.89          3.58          -7.89%
BenchmarkSectorWorld/IterateParallel/16384-8     2.21          2.09          -5.57%
BenchmarkSectorWorld/IterateParallel/65536-8     2.04          1.53          -25.13%
BenchmarkSectorWorld/IterateRadius/64-8          77.8          70.0          -10.05%
BenchmarkSectorWorld/IterateRadius/256-8         82.5          78.0          -5.45%
BenchmarkSectorWorld/IterateRadius/1024-8        115           111           -3.65%
BenchmarkSectorWorld/IterateRadius/4096-8        118           112           -5.26%
BenchmarkSectorWorld/IterateRadius/16384-8       122           115           -5.67%
BenchmarkSectorWorld/IterateRadius/65536-8       125           118           -5.77%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Performance related server Only related to the server
Projects
None yet
Development

No branches or pull requests

2 participants