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

Best way to scale integers #671

Closed
pjk6 opened this issue Sep 21, 2018 · 3 comments
Closed

Best way to scale integers #671

pjk6 opened this issue Sep 21, 2018 · 3 comments

Comments

@pjk6
Copy link

pjk6 commented Sep 21, 2018

Hi,

What would be the best way in P4 (P4_14) to scale integers to a certain range (where the size of the range is not a power of 2)?

Of course I can use the modify_field_with_hash_based_offset action, but one of the requirements is that the size must be a power of 2 (last argument). Suppose I want to scale a hash value of 16-bits to a range of 0-9 (so the size is equal to 10). How can I implement this in P4?

@jafingerhut
Copy link
Collaborator

Some P4 implementations do not have the restriction that the last argument to modify_field_with_hash_based_offset must be a power of 2, because they implement something like an integer modulo operation with a denominator that can be other values, e.g. 10.

There is no requirement that a P4 implementation support that, though. It is a good way to go if the implementations you care about do.

If an implementation you care about doesn't, talk to a device vendor to ask for suggestions, in case they have implemented something that suits your purposes.

However, if you are looking for ideas that might be most widely portable, you can look into bit-twiddling methods that have a long history in the internals of compilers for doing certain kinds of arithmetic on machines that are limited in their instruction sets, to operations like shift, add, subtract, but no multiply, divide, or modulo, and implementing those more complex operations using the simpler ones. One resource is "Hacker's Delight" by Henry S. Warren, http://www.hackersdelight.org Chapter 10 "Integer division by constants" probably has some things that are applicable, albeit they may require a fair number of shift, add, and subtract operations to get the correct result.

If you do not need modulo, but just "map any 16-bit value down to a range [0, 9]", you could use a ternary table matching on the 16-bit value and an action that sets the result, and by picking an appropriate collection of ternary entries you can get an equal number of 16-bit values mapping to each of the possibilities [0, 9].

@jafingerhut
Copy link
Collaborator

Oh, another hack-ish way might be to use an action selector implementation for a table, where there are 0 normal search key fields, and your 16-bit field as the only field to hash to select a member from a group. The action can assign the value of an action parameter to some metadata field where you want to store the result [0,9] (or whatever range). Then in your control plane software create one group, add 10 members, each with a different action parameter 0 thru 9, and create one table entry that points at that group.

Depending upon the action profile implementation in your target device, it might implement the modulo by 10, or it might use some other technique to get a nearly equal distribution of 16-bit values to the 10 actions.

@pjk6
Copy link
Author

pjk6 commented Sep 24, 2018

Thank you for your very clear answer! I like your approach with the 'mapping' table which maps a 16-bit value to the '0 - 9' range. This is working very well!

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

No branches or pull requests

2 participants