Shabtay, Responses below. I tried as best I could to incorporate what we discussed today to answer your questions and added some more detailed examples. It hope you'll find the responses fairly straightforward and that they make common sense. -- johnS Shabtay Matalon wrote: > John, > > Your email response to Jason confirmed the following semantics for pipes. >> > > >> > 3. The spec doesn’t explicitly define the HW/SW yield control > semantics when using pipes. Here is want we understand so far: > >> > > >> > Pipe is empty and receive() is called - Yield to producer > >> > Pipe is full and send() is called - Yield to consumer > >> > Pipe is not empty and flush() is called - Yield to consumer > >> > > >> > Is this correct? Shouldn’t the spec define explicitly the above > semantics? > >> > >>johnS: > >>Yes this is basically correct. We can add some more descriptive text*/ > /*there. > >> > >>-- johnS > >> > > I am wondering how the following scenario that uses data shaping would > work. I am looking at what you have defined as a nozzle meaning that the > BFM (producer) is writing elements one at a time, but the PM (consumer) > on the C side is reading the transaction (all the elements) as a whole. > > > > 1. Assume that pipe fills up while the producer has provided only > part of the elements and thus has not issued yet eom and flush. If this > cause the pipe to yield to the consumer (as defined above), the > dpi_pipe_c_receive method will still blocked until the entire > transaction is being written by the producer. This will result in a > deadlock as both sides are now waiting on each other. Is this correct or > I misunderstood how data shaping is supposed to work? johnS: This is solved by making the minimum granularity of the pipe a full transaction where a transaction is defined as the maximum # elements as defined on the H/W side in the pipe declaration. As we had discussed today, a pipe declaration is a fixed-named function with a fixed-sized data argument width within at least given module if not more globally. The same declaration serves all instances of pipes within that module distinguished by the intra-module pipe ID arguments. The bit width of the data argument in the pipe corresponds to the maximum possible number of elements making up the transaction which is basically, # bits of data width = max # elements * #bytes/element * 8 Data shaping can occur for elements within a transaction in a number up to and including the max # elements - but not more. To solve the issue you mention above, we make a requirement that the minimum buffer granularity in the implementation of the pipe is 1 transaction's worth of data. So, an implementation can have a buffer size of 1 or more transactions. By doing this, we avoid any deadlock that could arise due to a pipe filling up before all elements of a transaction because if there is room for 1 element, there is guaranteed room for all elements. > > > > 2. Assume also that the producer has chosen to call flush before > eom for whatever reason. The pipe protocol does not prohibit that by my > understanding. Correct? This is the “pipe is not empty; yield to > consumer” scenario. But again the consumer dpi_pipe_c_receive call will > still block as it is waiting on the entire transaction to be written. > What will happen in this case? johnS: This is solved by making any flush act as if a full transaction has just been sent by the producer even if only a partial one has. So let's consider two scenarios: ------------------------------------- Funnel: Producer writes 5 elements then issues a flush Consumer reads 1 element at a time. The infrastructure will return from the producer's send call when the 5th read has occured. This case is pretty straightforward should raise no concerns. ------------------------------------- Nozzle: Producer writes 3 elements 1 element at a time then does a flush. Consumer reads 5 elements at a time. This case is a little trickier. The producer has only written a partial transaction, then performed a flush. In this case the infrastructure assumes the transaction has been completed and this must satisfy the consumer's read request in order to avoid deadlock. The last 2 elements will be undefined in this case but the read will be completed (i.e. return from the consumer's call). ------------------------------------- Also, be sure not to mix eom with flush semantics. The two are completely independent. eom is simply a user specified flag that can accompany any written data. On the other end it will be read with the same data. How and when it is used is completely up to the user. It can be thought of a 1 bit extension of the user's data. It works completely independently of flush. That said, let's re-examine the two examples from the point of view of eom: ------------------------------------- Funnel: Producer writes 5 elements and marks with eom. Consumer reads 1 element at a time. On the 5th call to the pipe the consumer will see the eom flag set. ------------------------------------- Nozzle: Producer writes 3 elements 1 element at a time The 3rd element is accompanied with eom. The producer writes two more elements (neither of which set eom). Consumer reads 5 elements at a time. It sees eom set because at least one of the element writes making up the transaction had specified it. -- johnS <eom> > > > > Thank, > > > > Shabtay > > > > PS. I’ll probably read your response after the holidays. Happy Holidays > to everybody. > > > > >Received on Thu Jan 5 14:33:09 2006
This archive was generated by hypermail 2.1.8 : Thu Jan 05 2006 - 14:33:30 PST