[P4-dev] Where to implement if-else apart from control flow to set value

Antonin Bas antonin at barefootnetworks.com
Tue Aug 18 17:10:32 EDT 2015


Just adding my thoughts to LJ's.

1) First I thought I would emphasize that if statements can only appear in
the control flow and that primitive calls can only appear in action bodies.
This means that you are going to have to introduce new tables no matter
what.
You can use "match-less" tables, where the default action is used
indiscriminately:

*action write_val_1() {*


*    modify_field(local_metadata.minimum, local_metadata.val1);}*


*table t_write_val1 {*



*    actions { write_val_1; }}*

*// same thing for val2 and val3*

*// control flow*






*if ((local_metadata.val1 < local_metadata.val2) and (local_metadata.val1 <
local_metadata.val3)) {    apply(t_write_val_1);}else if
((local_metadata.val2 < local_metadata.val3) and (local_metadata.val2 <
local_metadata.val1)) { ... }else { ... }*
This means you would need 3 tables for 3 values.

We could introduce a 2-operand min() action primitive in P4, and get rid of
the if statements in the control flow. But you would need 2 stages (with
parallel semantics) to find the minimum of 3 values (although one table
would be enough with today's software switch, which uses serial semantics).

It may not be such a good idea but if you only have a limited set of
possible values for val1, val2 and val3, you may be able to simple use an
exact match table. Of course, if you have 16 possible values for each, you
already have to use a table of size 4096...

2) P4 specifies that actions use parallel semantics, so in theory for your
code you would need 2 successive actions called from 2 successive tables.
This assumes that most hardware actually enforce parallel semantics.
However if you are playing around with the P4 software switch, it uses
*serial* so you can bundle the 2 modify_field calls in the same action.

3) Many people find it confusing, so we are considering improving this. The
best thing to do is look at the ECMP example in 15.8.3 (p 88).
I can give an even simpler example that uses an action profile without the
hash selector:


*table ipv4_lpm {*

*    reads { ipv4.dstAddr: lpm; }*

*    action_profile: ipv4_nhops;*



*    size: 128K;}*

*action_profile ipv4_nhops {*

*    actions { drop; get_nhop_info; }*



*    size: 4096;}*
In this example my target will be able to store 128K ipv4 prefixes. However
I am taking advantage of the fact that my number of possible nexthops is
much smaller (4096). Using an action profile (and introducing a level of
indirection) lets me share nhops information between prefixes, thus
decreasing the amount of memory I need. Let's assume that the nhop
information I am storing is 16 bytes. Instead of using 128K * 16 bytes of
action data, I am only using 4K * 16 bytes. Also if I need to update the
information for one next hop, I only need to do it it one place (vs. for
each prefix). Actually the code above is logically equivalent to:


*action set_nhop_index(idx) {*

*    modify_field(meta.nhop_idx, idx);*


*}*
*table ipv4_lpm {*

*    reads { ipv4.dstAddr: lpm; }*

*    actions { set_nhop_index; }*



*    size: 128K;}*

*table ipv4_nhop {*
*    reads { *
*meta.nhop_idx: exact}*

*    actions { drop; get_nhop_info; }*



*    size: 4096;}*
One difference is that the action_profile approach removes the need for
index management by the control plane. When using an action_selector (ECMP
example), we can also expose some nicer runtime APIs (with the notion of
groups and members).


Best,

Antonin


On Tue, Aug 18, 2015 at 9:58 AM, LJ Wobker <ljw at barefootnetworks.com> wrote:

> One of the other (smarter) guys will correct me if I’m wrong, but given
> that you can’t do conditionals in actions, and you’re limited to doing a
> comparison per stage when you have dependent lookups, I think you can solve
> this in two ways (perhaps more that I’m not thinking of)
>
>
>
> Method one is effectively a bubble sort – in stage N you do a compare of
> your first two possible items and get the lowest, then store it.  Then in a
> subsequent stage, you do a comparison of that value and the max (or min)
> floats/bubbles to the top.  This becomes inefficient for large numbers of
> elements.
>
>
>
> If you’re willing to burn extra metadata, I think you’d be able to store
> all of your elements and then do a binary search style comparison… if you
> had for example 7 elements, you should be able to do 3 comparisons in the
> first stage, eliminating 3 non-minimum elements.  In stage N+1, you’d do
> two comparisons on the remaining 4 elements, eliminating 2 more.  Then in
> stage N+2 you’d choose between the last two.
>
>
>
> All of that said, I don’t think the language has a particular elegant way
> of doing min/max searching or sorting.  I know that this capability has
> been discussed, but given that the various implementations (targets) is
> very wide, some of those targets are unlikely to be able to efficiently
> sort/select values… so I’m not yet convinced that having this primitive
> makes sense.
>
>
>
> I’m sure others will also have thoughts on this…
>
>
>
>
>
> --lj
>
>
>
>
>
>
>
>
>
>
>
> *From:* P4-dev [mailto:p4-dev-bounces at p4.org] *On Behalf Of *Swaroop Thool
> *Sent:* Tuesday, August 18, 2015 5:41 PM
> *To:* p4-dev at p4.org
> *Subject:* [P4-dev] Where to implement if-else apart from control flow to
> set value
>
>
>
> Hi All,
>
> I am learning p4. I want to know where can steps be written to implement
> simple operations.
>
> 1)  Where can I put snippet shown below which can set a field of
> metadata/register means, in control flow or action only? for example: If I
> want to use if-else statement where comparison between metadata fields are
> considered and output of it should set one field from that metadata.
> I have seen if-else are only used to call "apply(table)" in control part
> and I also cannot carry out if-else in action definition of that table.
>
> Above example: I didnt find syntax to directly find minimum among three.
> This is simple snippet to find minimum of three. I get syntax error when I
> tried to use in control or action part. So I want to use like this without
> creating new table.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> *      if ((local_metadata.val1 < local_metadata.val2) and
> (local_metadata.val1 < local_metadata.val3)){
> modify_field(local_metadata.minimum, local_metadata.val1)       }      else
> if ((local_metadata.val2 < local_metadata.val3) and (local_metadata.val2 <
> local_metadata.val1)){                modify_field(local_metadata.minimum,
> local_metadata.val2)      }      else
> modify_field(local_metadata.minimum, local_metadata.val3) How can this be
> implemented in p4 terms and inside what?2) I came across serial and
> parallel semantics. What if I want use value of 1st modify_field() into
> next modify_field() under same action definition. Is parallel behaviour can
> be changed?3) I am unclear with Action Profile part of specification to
> implement it. Can anyone explain it?*Thanks,
> Swaroop
>
> _______________________________________________
> P4-dev mailing list
> P4-dev at p4.org
> Listinfo - http://mail.p4.org/mailman/listinfo/p4-dev_p4.org
> Archives - http://mail.p4.org/pipermail/p4-dev_p4.org/
>



-- 
Antonin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.p4.org/pipermail/p4-dev_lists.p4.org/attachments/20150818/9896e1ee/attachment-0001.html>


More information about the P4-dev mailing list