Skip to content

parser: accelerate DecodeLayers#657

Closed
yerden wants to merge 1 commit intogoogle:masterfrom
yerden:decoding-layers-accel
Closed

parser: accelerate DecodeLayers#657
yerden wants to merge 1 commit intogoogle:masterfrom
yerden:decoding-layers-accel

Conversation

@yerden
Copy link
Copy Markdown
Contributor

@yerden yerden commented May 28, 2019

Most of frequently used (and natively supported) LayerType values are not very big, so we may attempt to use array to search DecodingLayer, fallback to map only if LayerType is too big. Similar approach as in RegisterLayerType. I chose 256 as a decent threshold.

Results on Xeon(R) CPU E5-2620:

benchmark                                      old ns/op     new ns/op     delta
BenchmarkDecodingLayerParserIgnorePanic-32     227           191           -15.86%
BenchmarkDecodingLayerParserHandlePanic-32     291           227           -21.99%

Attempt to use array to search DecodingLayer, fallback
to map only if LayerType is too big.

Signed-off-by: Yerden Zhumabekov <[email protected]>
@yerden
Copy link
Copy Markdown
Contributor Author

yerden commented May 30, 2019

And one more thing. I don't want to overgeneralize (and please correct me if i'm wrong) but I suspect that most common usage pattern here suggests not so many DecodingLayer-s in a single DecodingLayerParser. Most of the time, up to ten layers is enough.

If that's true, naive linear search of DecodingLayer beats map, my laptop (Core i5-3320M) tests:

BenchmarkSearchMap3-4       	30000000	        50.4 ns/op
BenchmarkSearchMap5-4       	30000000	        56.2 ns/op
BenchmarkSearchMap10-4      	20000000	        73.2 ns/op

BenchmarkSearchArray3-4     	30000000	        40.2 ns/op
BenchmarkSearchArray5-4     	30000000	        39.3 ns/op
BenchmarkSearchArray10-4    	30000000	        39.5 ns/op

BenchmarkSearchLinear3-4    	30000000	        45.2 ns/op
BenchmarkSearchLinear5-4    	30000000	        50.0 ns/op
BenchmarkSearchLinear10-4   	30000000	        52.8 ns/op

That's a definite win if some custom LayerType values are in use, so you don't want to use array indexing (too big values).

And, in case of a simple Eth->IPv4->TCP packet, about 60-70% of DecodeLayers() call duration amounts to searching for an appropriate DecodingLayer rather than layer decoding itself.

@yerden
Copy link
Copy Markdown
Contributor Author

yerden commented May 30, 2019

I will investigate other ways to boost performance and will return later.

@yerden yerden closed this May 30, 2019
@gconnell
Copy link
Copy Markdown
Contributor

Hey, yerden,

This looked super promising; is there a reason the PR was closed out?

@yerden
Copy link
Copy Markdown
Contributor Author

yerden commented May 30, 2019

Well, other ideas came up to me, like:

  1. DecodingLayerParser doesn't consider level of a layer. For example, LayerTypeEthernet may encounter at the beginning only, rather than in the middle of a packet, so when looking for the first level decoder, layers.Ethernet should be the primary suspect to test against.

  2. As I said earlier, in case we have only few decoders, linear search is preferable to map.

  3. Proposed approach is good when using gopacket-owned LayerType values but it doesn't work when working with custom LayerType values. Maybe we should implement different array for values >1000.

  4. Maybe we could provide end-user with a tool to supply his own map implementation for LayerType->DecodingLayer lookup. This would require to break API.

So... I thought I should take a break, test these ideas and revisit later. Or, alternatively, I can simply reopen this PR, allow it to merge and work on it for next PR. Any ideas?

@yerden yerden reopened this May 30, 2019
@yerden yerden closed this Jun 2, 2019
@yerden yerden deleted the decoding-layers-accel branch June 20, 2019 15:45
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.

2 participants