How to get queue size periodically to calculate any statistical parameter like average,mean,median,variance?

The details of the question can be found on this github issue: How to get queue size periodically to calculate any statistical parameter like average,mean,median,variance? · Issue #1168 · p4lang/behavioral-model · GitHub

Basic idea is we want to calculate average queue size of a p4 switch in a simple topology with a bottleneck link.Now the way we generate the traffic is same from h1 to h2 , the way queue size is getting filled is also same, hence the average would always be same until topology is changed.

So if we want to see different queue sizes, how can it be done?

You can do what you wish using a P4 register, e.g. one with a separate entry per queue for which you want to maintain an average queue depth.

In each element of the P4 register, you could store the following:

  • some measure of the average queue depth, A, chosen by you
  • the time T (e.g. egress_global_timestamp value) when that queue depth was observed

When you process a packet in egress, you can read the current state for the queue, and using those values plus the current time T_now and queue depth Q, calculate a new average queue depth A_now, and write the new values A_now and T_now back to the P4 register index that you read from.

It is up to you how fancy you want to get with calculating the new value A_now. You could use an exponentially weighted moving average with a time constant C, calculated as some approximation of the following formula:

A_now = A + (A_now - A) * exp((T_now - T) / C)

or something cheaper than that. As ideas for ways to do such a calculation in P4 with only table lookups, shifts, and add/subtract, see this article:

Note: Tofino has a “Low Pass Filter” extern that implements a feature like the above, without a developer having to implement it all themselves, called Lpf here: Open-Tofino/tofino1_base.p4 at master · barefootnetworks/Open-Tofino · GitHub because calculating exponentially weighted moving averages is a fairly useful thing in high performance data planes.

When we have 2 links connected to a link, will this mean switch will maintain 2 separate queues for 2 links?

Link 1 s1 to s2, Link 2 s1 to s3

s1 — s2
|
s3

The queueing metadata only will show 1 value of queue depth at any point of time for s1, should this differentiation be done using egress port which will be different for s1-s2 and s1-s3?

I do not understand the phrase “When we have 2 links connected to a link”. If you can clarify what you mean by that phrase, I might understand the first question you tried to ask.

In your second question, you use the phrase “should this differentiation be done”. I am not sure what you mean by that, either. Are you wanting to compare the depths of queues for two different queues in a single switch to each other, for some reason? If yes, I am curious what reason you have for wanting to compare the depths of two different queues to each other?

If you do not want to compare the depths of two different queues to each other, then I do not understand the meaning of your last question at all.

In general, yes, the metadata built into v1model only lets you view queue depth information, during egress processing, for a single queue, the one queue that the packet just passed through.

If you want to read queue depths for other queues besides the one that the packet passed through, see my recent answer to another question for ideas where you can maintain the queue depths you want in a P4 register, either in ingress, or in egress, or a separate P4 register in each, if you wish. What is the queue management approach in P4? - #10 by andyfingerhut

2 connected links meaning s1 is connected to 2 switches, s2 and s3, now will s1 maintain 2 queues 1 for port on s2 and 1 for port on s3 or will it be only 1 queue at s1 where packets for both s2 and s3 will be added ?

My underlying question is whether each port in a switch will have a separate queue or not? and i think yes it does then how to get the size for each as in metadata we have only 1 variable deq_qdepth

Yes, typically switch ASICs have a separate FIFO queue of packets for each output port. Also typically, they have multiple separate FIFO queues of packets for each output port, e.g. because you might want to put packets into a queue based on various criteria, e.g. classify packets into high/medium/low priority, and put the packets into separate queues based upon that decision, and configure a packet scheduling algorithm among those queues that lets more high priority packets go when the link is full, versus low priority packets are forced to wait.

The linked answer in my previous answer above should give you som ideas on how to read multiple queue depths while processing a single packet. Please read that, and ask again if it does not address your question.

1 Like

@rohanpadshah68 asked in another forum, but I am adding it here as a follow-up, with brief answer: " Can you please clarify what value can C take here? What do you exactly mean by “With a time constant C”

A_now = A + (A_now - A) * exp((T_now - T) / C)

In that formula C is a constant that you pick, depending upon your purposes. If C is 1 microsecond, for example, then the effect of older values “decays” much faster than if C is 1 millisecond.

Thanks for the response!

“They have multiple separate FIFO queues of packets for each output port”

Can I interpret this phrase like this: suppose a switch has 2 ports, each with 8 queues, so there are 16 queues in total on this switch?

Yes, that is how you can interpret it.