Hi, I had posted the following questions earlier. Some insight will be greatly appreciated. Thanks - Mrinal
Mrinal Nath wrote: > Hi, > > I have a few questions about the Flexus implementation: > > 1. In IFetchImpl.cpp, in function "memoryResponse", the reply for a > "Probe" is always "ProbedNotPresent". Can you please clarify the reason > for this. (I think that since this is the IFetch component, it does not > cache anything, and so no probe will hit. However, then why does this > component even get Invalidate or Downgrade requests?) > > In fact, can you please clarify the communication that goes on between > the L1-L2 caches, and the L1i-IFetch and the L1d-Execute ? > > 2. In ExecuteImpl.cpp, in class ExecuteStateImpl, what is the exact > meaning of 'theIsIssued', 'theIsInitiated', 'theIsPerformed' and > 'theIsComplete'. To me, the first two seem similar to each other. Whats > the difference between them? The last two also seem similar to each other. > > > Thanks, > - Mrinal > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex From mrinal at ece.umn.edu Thu Sep 14 06:19:34 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Thu Sep 14 06:19:44 2006 Subject: [Simflex] What is the difference between Request and Snoop In-Reply-To: <[email protected]> References: <[email protected]> Message-ID: <[email protected]> Hi, I wanted to know the difference between "snoop" and "request". By looking at the function 'runSnoopProcess' in CacheController.hpp, it seems to me that snoops are only related to instruction fetches. Also, can someone please clarify the flow of messages in the cache hierarchy. (who sends what types of messages to whom under what conditions?) Any help will be greatly appreciated. Thanks - Mrinal Mrinal Nath wrote: > Hi, > > I have a few questions about the Flexus implementation: > > 1. In IFetchImpl.cpp, in function "memoryResponse", the reply for a > "Probe" is always "ProbedNotPresent". Can you please clarify the reason > for this. (I think that since this is the IFetch component, it does not > cache anything, and so no probe will hit. However, then why does this > component even get Invalidate or Downgrade requests?) > > In fact, can you please clarify the communication that goes on between > the L1-L2 caches, and the L1i-IFetch and the L1d-Execute ? > > 2. In ExecuteImpl.cpp, in class ExecuteStateImpl, what is the exact > meaning of 'theIsIssued', 'theIsInitiated', 'theIsPerformed' and > 'theIsComplete'. To me, the first two seem similar to each other. Whats > the difference between them? The last two also seem similar to each other. > > > Thanks, > - Mrinal > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex From mrinal at ece.umn.edu Thu Sep 14 06:55:26 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Thu Sep 14 06:55:41 2006 Subject: [Simflex] What is the difference between Request and Snoop In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> Message-ID: <[email protected]> Sorry for the spamming, but could some one also describe what a "probe" is (this is related to the state kwaitProbe in the MAF in CacheController.hpp) How is it different from a snoop or a request. Or is it the same as a snoop ? Thanks ! - Mrinal Mrinal Nath wrote: > Hi, > > I wanted to know the difference between "snoop" and "request". > > By looking at the function 'runSnoopProcess' in CacheController.hpp, it > seems to me that snoops are only related to instruction fetches. > > Also, can someone please clarify the flow of messages in the cache > hierarchy. (who sends what types of messages to whom under what > conditions?) > > Any help will be greatly appreciated. > Thanks > - Mrinal > > > Mrinal Nath wrote: > >> Hi, >> >> I have a few questions about the Flexus implementation: >> >> 1. In IFetchImpl.cpp, in function "memoryResponse", the reply for a >> "Probe" is always "ProbedNotPresent". Can you please clarify the reason >> for this. (I think that since this is the IFetch component, it does not >> cache anything, and so no probe will hit. However, then why does this >> component even get Invalidate or Downgrade requests?) >> >> In fact, can you please clarify the communication that goes on between >> the L1-L2 caches, and the L1i-IFetch and the L1d-Execute ? >> >> 2. In ExecuteImpl.cpp, in class ExecuteStateImpl, what is the exact >> meaning of 'theIsIssued', 'theIsInitiated', 'theIsPerformed' and >> 'theIsComplete'. To me, the first two seem similar to each other. Whats >> the difference between them? The last two also seem similar to each >> other. >> >> >> Thanks, >> - Mrinal >> _______________________________________________ >> SimFlex mailing list >> [email protected] >> https://sos.ece.cmu.edu/mailman/listinfo/simflex >> SimFlex web page: http://www.ece.cmu.edu/~simflex > > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex From twenisch at ece.cmu.edu Thu Sep 14 13:51:01 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Thu Sep 14 13:51:06 2006 Subject: [Simflex] Some questions In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> Message-ID: <[email protected]> Mrinal, Apologies, I must have overlooked your message. On Thu, 14 Sep 2006, Mrinal Nath wrote: > Hi, > I had posted the following questions earlier. Some insight will be greatly > appreciated. > Thanks > - Mrinal > > Mrinal Nath wrote: >> Hi, >> >> I have a few questions about the Flexus implementation: >> >> 1. In IFetchImpl.cpp, in function "memoryResponse", the reply for a >> "Probe" is always "ProbedNotPresent". Can you please clarify the reason >> for this. (I think that since this is the IFetch component, it does not >> cache anything, and so no probe will hit. However, then why does this >> component even get Invalidate or Downgrade requests?) Probe messages are used to maintain coherence between the L1 I and L1 D caches. Basically, if an instruction access misses in L1 I and L2, a probe message is sent to L1D to check if the line is present there. The SPARC archictecture doesn't actually require the I and D caches to be coherent. However, our DSM coherence protocol requires this (the Probe works around a specific case: when a cache block is not present in L1I or L2, but present and dirty in L1D. This case is rare, but does happen. Without Probes, this case would result an error in our coherence protocol). As you noted, the IFetch component doesn't cache anything, so it always replies with ProbedNotPresent when it receives a Probe. The in-order core also has no need for Invalidate and Downgrade messages. (The out-of-order core does use these messages to enforce multiprocessor memory ordering constraints in the load-store queue). The only reason we send these messages to the IFetch is to simplify the cache code - a cache has no idea if it is the top level of the cache heirarchy, so all the caches pass these messages up, and the IFetch component starts the response propagation back down the hierarchy. >> >> In fact, can you please clarify the communication that goes on between >> the L1-L2 caches, and the L1i-IFetch and the L1d-Execute ? >> >> 2. In ExecuteImpl.cpp, in class ExecuteStateImpl, what is the exact >> meaning of 'theIsIssued', 'theIsInitiated', 'theIsPerformed' and >> 'theIsComplete'. To me, the first two seem similar to each other. Whats >> the difference between them? The last two also seem similar to each other. >> I'm a bit rusty on the in-order core (everyone here is using TraceFlex or the out-of-order simulator now), but from a quick look at the code: issue() is called at the time an instruction is received by the Execute component. This tells the InorderSimicsFeeder component to execute the instruction. For non memory instructions, this causes the instruction to be marked as "performed". For memory instructions, nothing happens yet. initiate() is called for memory operations when they are sent to the memory system (L1D). It is used for bookkeeping (so a memory operation is not sent twice). perform() is called at the moment in time that a memory operation should take effect, that is, the moment where a load is bound to a value and a store value becomes visible to other processors in the system. It is usually called when a reply returns from the memory system. This function also causes the InorderSimicsFeeder to trigger the load or store in Simics. complete() is called when an instruction is done, and tells the InorderSimicsFeeder that it can forget the instruction and move on to the next one. Hope that helps. Regards, -Tom Wenisch >> >> Thanks, >> - Mrinal >> _______________________________________________ >> SimFlex mailing list >> [email protected] >> https://sos.ece.cmu.edu/mailman/listinfo/simflex >> SimFlex web page: http://www.ece.cmu.edu/~simflex > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex > From twenisch at ece.cmu.edu Thu Sep 14 14:14:17 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Thu Sep 14 14:14:21 2006 Subject: [Simflex] What is the difference between Request and Snoop In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi, On Thu, 14 Sep 2006, Mrinal Nath wrote: > Hi, > > I wanted to know the difference between "snoop" and "request". In general, Snoop messages have to do with coherence, while Request messages initiate new memory transactions. Both the Snoop and Request channels travel "down" the cache hierarchy (from the CPU towards memory). The reason we separate the two channels again has to do with our DSM coherence protocol. The key requirement for the coherence protocol to work is that invalidations and downgrades cannot be blocked by request messages (that is; an invalidation reply has to be sent even if there are request messages that were issued before it that are waiting to be serviced by the memory system). If the invalidation/downgrade were stuck in a queue behind a request, the protocol can deadlock. Thus, we separate requests and coherence messages into two virtual channels, Snoop and Request. Each channel has separate queue and buffering resources. Messages in the Snoop channel can bypass messages in the request channel (i.e., a snoop message may be processed by the cache before a request message even if the request message arrived earlier). However, Requests may not bypass snoops (a snoop message that arrives earlier *must* be processed before any new request messages). Note that in some cases, when a snoop bypasses a request, it modifies the request message. The simplest example of this arises when a clean line is upgraded. Initially the line is present in L1D and clean, and the CPU stores to the line. The L1D sends an UpgradeRequest to L2. Now, while the Upgrade is still pending, an invalidation arrives for the line, and L1D invalidates its copy. When the InvalidationAck is processed by L2, the UpgradeRequest is changed to a WriteRequest, because L1 now needs data as well as permission for the line. As a side note, all messages which carry data away from the CPU (e.g., InvUpdateAck, EvictDirty, ...) travel in the Snoop channel. You can see exactly which messages use the snoop channel in Common/Slices/MemoryMessage.hpp. Look for the usesSnoopChannel() function. Let me know if you have questions about specific message types in MemoryMessage.hpp. Note that there are some message types in there that are not used in the simulation models we have released publicly (e.g., the FlushReq). Regards, -Tom Wenisch Computer Architecture Lab Carnegie Mellon University > > By looking at the function 'runSnoopProcess' in CacheController.hpp, it seems > to me that snoops are only related to instruction fetches. > > Also, can someone please clarify the flow of messages in the cache hierarchy. > (who sends what types of messages to whom under what conditions?) > > Any help will be greatly appreciated. > Thanks > - Mrinal > > From twenisch at ece.cmu.edu Thu Sep 14 14:15:30 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Thu Sep 14 14:15:33 2006 Subject: [Simflex] What is the difference between Request and Snoop In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi, I believe I covered this in my first reply. Let me know if it is still unclear. Regards, -Tom Wenisch On Thu, 14 Sep 2006, Mrinal Nath wrote: > Sorry for the spamming, but could some one also describe what a "probe" is > (this is related to the state kwaitProbe in the MAF in > CacheController.hpp) > > How is it different from a snoop or a request. Or is it the same as a snoop ? > > Thanks ! > - Mrinal > From mrinal at ece.umn.edu Fri Sep 15 05:30:50 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Fri Sep 15 05:31:00 2006 Subject: [Simflex] Some questions In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Tom, Thanks a lot for your responses. It was indeed helpful. I have one quick question though: the 'perform()' function (in PerformInstruction.cpp is only performing STORES. It is causing the value stored in the StoreBuffer to be written into Simics (correct ?). This function does not take care of LOADS. Where are LOADS being 'performed' and what does 'performing' a load mean? (does it mean always reading from store buffer or reading from Simics if not found in store buffer? Please point to parts of the code where this is happening) Also, can you explain what the 'SIM_set_mem_op_value_cpu' in 'trace_snoop_operate' function in SimicsTracer.hpp does ? Regards - Mrinal Thomas Wenisch wrote: > Mrinal, > > Apologies, I must have overlooked your message. > > On Thu, 14 Sep 2006, Mrinal Nath wrote: > >> Hi, >> I had posted the following questions earlier. Some insight will be >> greatly appreciated. >> Thanks >> - Mrinal >> >> Mrinal Nath wrote: >> >>> Hi, >>> >>> I have a few questions about the Flexus implementation: >>> >>> 1. In IFetchImpl.cpp, in function "memoryResponse", the reply for a >>> "Probe" is always "ProbedNotPresent". Can you please clarify the reason >>> for this. (I think that since this is the IFetch component, it does not >>> cache anything, and so no probe will hit. However, then why does this >>> component even get Invalidate or Downgrade requests?) > > > Probe messages are used to maintain coherence between the L1 I and L1 D > caches. Basically, if an instruction access misses in L1 I and L2, a > probe message is sent to L1D to check if the line is present there. The > SPARC archictecture doesn't actually require the I and D caches to be > coherent. However, our DSM coherence protocol requires this (the Probe > works around a specific case: when a cache block is not present in L1I > or L2, but present and dirty in L1D. This case is rare, but does happen. > Without Probes, this case would result an error in our coherence protocol). > > As you noted, the IFetch component doesn't cache anything, so it always > replies with ProbedNotPresent when it receives a Probe. The in-order > core also has no need for Invalidate and Downgrade messages. (The > out-of-order core does use these messages to enforce multiprocessor > memory ordering constraints in the load-store queue). The only reason > we send these messages to the IFetch is to simplify the cache code - a > cache has no idea if it is the top level of the cache heirarchy, so all > the caches pass these messages up, and the IFetch component starts the > response propagation back down the hierarchy. > >>> >>> In fact, can you please clarify the communication that goes on between >>> the L1-L2 caches, and the L1i-IFetch and the L1d-Execute ? >>> >>> 2. In ExecuteImpl.cpp, in class ExecuteStateImpl, what is the exact >>> meaning of 'theIsIssued', 'theIsInitiated', 'theIsPerformed' and >>> 'theIsComplete'. To me, the first two seem similar to each other. Whats >>> the difference between them? The last two also seem similar to each >>> other. >>> > > I'm a bit rusty on the in-order core (everyone here is using TraceFlex > or the out-of-order simulator now), but from a quick look at the code: > > issue() is called at the time an instruction is received by the Execute > component. This tells the InorderSimicsFeeder component to > execute the instruction. For non memory instructions, this > causes the instruction to be marked as "performed". For memory > instructions, nothing happens yet. > > initiate() is called for memory operations when they are sent to the > memory system (L1D). It is used for bookkeeping (so a memory > operation is not sent twice). > > perform() is called at the moment in time that a memory operation should > take effect, that is, the moment where a load is bound to a > value and a store value becomes visible to other processors in > the system. It is usually called when a reply returns from the > memory system. This function also causes the > InorderSimicsFeeder to trigger the load or store in Simics. > > complete() is called when an instruction is done, and tells the > InorderSimicsFeeder that it can forget the instruction and move > on to the next one. > > Hope that helps. > > Regards, > -Tom Wenisch > >>> >>> Thanks, >>> - Mrinal >>> _______________________________________________ >>> SimFlex mailing list >>> [email protected] >>> https://sos.ece.cmu.edu/mailman/listinfo/simflex >>> SimFlex web page: http://www.ece.cmu.edu/~simflex >> >> _______________________________________________ >> SimFlex mailing list >> [email protected] >> https://sos.ece.cmu.edu/mailman/listinfo/simflex >> SimFlex web page: http://www.ece.cmu.edu/~simflex >> > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex From mrinal at ece.umn.edu Fri Sep 15 06:30:31 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Fri Sep 15 06:30:38 2006 Subject: [Simflex] How to detect haps? In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi, I had a question related to using Simics 'haps' within the Flexus simulator. I have created a magic breakpoint (sparc) so that Simics will break the simulation when this particular magic instruction is executed by Simics. I want Flexus to know that this particular magic instruction has been seen by Simics and therefore execute some particular function. How can I go about achieving this? Thanks - Mrinal From twenisch at ece.cmu.edu Fri Sep 15 12:37:23 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Fri Sep 15 12:37:29 2006 Subject: [Simflex] Some questions In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Mrinal, Flexus' handling of loads and stores is somewhat strange in that we actually override Simics normal processing and peek/poke values directly into Simics' memory image. We do this so that we can implement the total-store-order (TSO) memory consistency model. Unlike sequential consistency (SC), in TSO, it is possible for a memory location to temporarily appear to have several different values, one per CPU. Our StoreBuffer implementation tracks the value visible to each CPU, and overrides the values that would have been returned by Simics as neccessary. I answer your specific questions below. On Fri, 15 Sep 2006, Mrinal Nath wrote: > Hi Tom, > Thanks a lot for your responses. It was indeed helpful. > > I have one quick question though: the 'perform()' function (in > PerformInstruction.cpp is only performing STORES. It is causing the value > stored in the StoreBuffer to be written into Simics (correct ?). This > function does not take care of LOADS. Yes, as you deduced, Flexus overrides the value of all store instructions in perform(), by copying the value from Flexus' store buffer into Simics' memory image. We suppress Simics' normal processing of stores by setting the ignore flag in InorderSimicsFeeder/SimicsTracer.hpp real_hier_operate(). Thus, Simics does not record the stores value. Instead, we track the value in our StoreBuffer. At the time the store becomes globally visible (the store commits to the memory hierarchy), we copy the stores value to Simics' memory, which happens in perform(). > > Where are LOADS being 'performed' and what does 'performing' a load mean? > (does it mean always reading from store buffer or reading from Simics if not > found in store buffer? Please point to parts of the code where this is > happening) Loads get their value in InorderSimicsFeeder/SimicsTracer.hpp trace_snoop_operate(). This method implements Simics' "timing_model" interface and is connected to the snoop_device attribute of each CPU (you can look these interfaces up in the Simics documentation). trace_snoop_operate is called for each load and store operation after the operation has "happened" (that is, after Simics has done the load or store). When Simics calls this function, we check to see if there is a value in the StoreBuffer for that location that is visible to the requesting CPU. If there is, we return that value, by calling SIM_set_mem_op_value_cpu() (which overrides the return value of a load). If there is no matching value in the StoreBuffer, we let Simics return the value it read from its memory image. > > Also, can you explain what the 'SIM_set_mem_op_value_cpu' in > 'trace_snoop_operate' function in SimicsTracer.hpp does ? > > Regards > - Mrinal > Best Regards, -Tom Wenisch Computer Architecture Lab Carnegie Mellon University From twenisch at ece.cmu.edu Fri Sep 15 12:39:06 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Fri Sep 15 12:39:10 2006 Subject: [Simflex] How to detect haps? In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Mrinal, Take a look at the MagicBreak component to see examples of how to catch haps (including the Core_Magic_Instruction hap). Best Regards, -Tom Wenisch Computer Architecture Lab Carnegie Mellon University On Fri, 15 Sep 2006, Mrinal Nath wrote: > Hi, > I had a question related to using Simics 'haps' within the Flexus simulator. > > I have created a magic breakpoint (sparc) so that Simics will break the > simulation when this particular magic instruction is executed by Simics. I > want Flexus to know that this particular magic instruction has been seen by > Simics and therefore execute some particular function. How can I go about > achieving this? > > Thanks > - Mrinal > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex > From mrinal at ece.umn.edu Sat Sep 16 06:22:17 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Sat Sep 16 06:22:28 2006 Subject: [Simflex] Some questions In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Tom, I had another question related to probes (this is not directly related to Flexus implementation): In general, instruction and data pages of an application are on different pages of memory. (I am referring to the 'coff' file format used in unix systems). The I-pages are usually marked as read-only in the TLB, and an attempt to write to such pages will cause an exception (please correct me if I am wrong). In your explanation below about the probe messages, you said that the D-cache could contain a I-block. And that too, in a dirty state. I can't see how such a case can arise: firstly, I-pages are separate, so how could a I-block get into the D-cache? And secondly, the I-block should have been read-only. How could it become dirty on the D-cache ? Regards - Mrinal Thomas Wenisch wrote: > Mrinal, > > Apologies, I must have overlooked your message. > > On Thu, 14 Sep 2006, Mrinal Nath wrote: > >> Hi, >> I had posted the following questions earlier. Some insight will be >> greatly appreciated. >> Thanks >> - Mrinal >> >> Mrinal Nath wrote: >> >>> Hi, >>> >>> I have a few questions about the Flexus implementation: >>> >>> 1. In IFetchImpl.cpp, in function "memoryResponse", the reply for a >>> "Probe" is always "ProbedNotPresent". Can you please clarify the reason >>> for this. (I think that since this is the IFetch component, it does not >>> cache anything, and so no probe will hit. However, then why does this >>> component even get Invalidate or Downgrade requests?) > > > Probe messages are used to maintain coherence between the L1 I and L1 D > caches. Basically, if an instruction access misses in L1 I and L2, a > probe message is sent to L1D to check if the line is present there. The > SPARC archictecture doesn't actually require the I and D caches to be > coherent. However, our DSM coherence protocol requires this (the Probe > works around a specific case: when a cache block is not present in L1I > or L2, but present and dirty in L1D. This case is rare, but does happen. > Without Probes, this case would result an error in our coherence protocol). > > As you noted, the IFetch component doesn't cache anything, so it always > replies with ProbedNotPresent when it receives a Probe. The in-order > core also has no need for Invalidate and Downgrade messages. (The > out-of-order core does use these messages to enforce multiprocessor > memory ordering constraints in the load-store queue). The only reason > we send these messages to the IFetch is to simplify the cache code - a > cache has no idea if it is the top level of the cache heirarchy, so all > the caches pass these messages up, and the IFetch component starts the > response propagation back down the hierarchy. > >>> >>> In fact, can you please clarify the communication that goes on between >>> the L1-L2 caches, and the L1i-IFetch and the L1d-Execute ? >>> >>> 2. In ExecuteImpl.cpp, in class ExecuteStateImpl, what is the exact >>> meaning of 'theIsIssued', 'theIsInitiated', 'theIsPerformed' and >>> 'theIsComplete'. To me, the first two seem similar to each other. Whats >>> the difference between them? The last two also seem similar to each >>> other. >>> > > I'm a bit rusty on the in-order core (everyone here is using TraceFlex > or the out-of-order simulator now), but from a quick look at the code: > > issue() is called at the time an instruction is received by the Execute > component. This tells the InorderSimicsFeeder component to > execute the instruction. For non memory instructions, this > causes the instruction to be marked as "performed". For memory > instructions, nothing happens yet. > > initiate() is called for memory operations when they are sent to the > memory system (L1D). It is used for bookkeeping (so a memory > operation is not sent twice). > > perform() is called at the moment in time that a memory operation should > take effect, that is, the moment where a load is bound to a > value and a store value becomes visible to other processors in > the system. It is usually called when a reply returns from the > memory system. This function also causes the > InorderSimicsFeeder to trigger the load or store in Simics. > > complete() is called when an instruction is done, and tells the > InorderSimicsFeeder that it can forget the instruction and move > on to the next one. > > Hope that helps. > > Regards, > -Tom Wenisch > >>> >>> Thanks, >>> - Mrinal >>> _______________________________________________ >>> SimFlex mailing list >>> [email protected] >>> https://sos.ece.cmu.edu/mailman/listinfo/simflex >>> SimFlex web page: http://www.ece.cmu.edu/~simflex >> >> _______________________________________________ >> SimFlex mailing list >> [email protected] >> https://sos.ece.cmu.edu/mailman/listinfo/simflex >> SimFlex web page: http://www.ece.cmu.edu/~simflex >> > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex From mrinal at ece.umn.edu Sat Sep 16 14:22:23 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Sat Sep 16 14:22:31 2006 Subject: [Simflex] How to detect haps? In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Tom, Thanks for the reply. I was able to write a function similar to EndOfParallelTracker (in BreakpointTracker.cpp) and get it to execute when my hap occurs. Now I have another problem: I want to access member functions of InorderSimicsFeeder or SimicsTracer from the above function that I am talking about. But I don't know the "name" of the object/pointer of the InorderSimicsFeeder component class. (e.g. the EndOfParallelTracker accesses theFlexus->terminateSimulation). Is there some handle like "theFeeder" or "theFlexus->theFeeder" or something similar by which I can access a member function of InorderSimicsFeeder? If there is no such name, then how can I go about achieving this? Thanks :) - Mrinal Thomas Wenisch wrote: > Hi Mrinal, > > Take a look at the MagicBreak component to see examples of how to catch > haps (including the Core_Magic_Instruction hap). > > Best Regards, > -Tom Wenisch > Computer Architecture Lab > Carnegie Mellon University > > On Fri, 15 Sep 2006, Mrinal Nath wrote: > >> Hi, >> I had a question related to using Simics 'haps' within the Flexus >> simulator. >> >> I have created a magic breakpoint (sparc) so that Simics will break >> the simulation when this particular magic instruction is executed by >> Simics. I want Flexus to know that this particular magic instruction >> has been seen by Simics and therefore execute some particular >> function. How can I go about achieving this? >> >> Thanks >> - Mrinal >> _______________________________________________ >> SimFlex mailing list >> [email protected] >> https://sos.ece.cmu.edu/mailman/listinfo/simflex >> SimFlex web page: http://www.ece.cmu.edu/~simflex >> > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex From twenisch at ece.cmu.edu Sat Sep 16 14:37:02 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Sat Sep 16 14:37:09 2006 Subject: [Simflex] Some questions In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Mrinal, In general, what you say below is true. However, remember that Simics and Flexus are full-system simulators. Code has to be loaded from somewhere (e.g., disk). It may arrive via DMA, but it may also be memcpy'd (for example, the kernel may copy it from I/O buffers to newly allocated pages, which are subsequently marked read-only). In a physically-indexed cache, the pages may still be in the D-cache when they start executing. However, in the cases I have seen Probe hits, we believe the actual culprit are shared library stubs. When a shared library is loaded, the runtime system fills in stub functions with the address to jump to when a function in the shared library is called. These stub functions are written dynamically, then subsequently executed. Finally, though self-modifying code is rare, it certainly does exist (e.g., JIT compilation in optimizing JVMs). Regards, -Tom Wenisch On Sat, 16 Sep 2006, Mrinal Nath wrote: > Hi Tom, > I had another question related to probes (this is not directly related to > Flexus implementation): > > In general, instruction and data pages of an application are on different > pages of memory. (I am referring to the 'coff' file format used in unix > systems). The I-pages are usually marked as read-only in the TLB, and an > attempt to write to such pages will cause an exception (please correct me if > I am wrong). > > In your explanation below about the probe messages, you said that the D-cache > could contain a I-block. And that too, in a dirty state. > > I can't see how such a case can arise: firstly, I-pages are separate, so how > could a I-block get into the D-cache? And secondly, the I-block should have > been read-only. How could it become dirty on the D-cache ? > > Regards > - Mrinal > > Thomas Wenisch wrote: >> Mrinal, >> >> Apologies, I must have overlooked your message. >> >> On Thu, 14 Sep 2006, Mrinal Nath wrote: >> >>> Hi, >>> I had posted the following questions earlier. Some insight will be greatly >>> appreciated. >>> Thanks >>> - Mrinal >>> >>> Mrinal Nath wrote: >>> >>>> Hi, >>>> >>>> I have a few questions about the Flexus implementation: >>>> >>>> 1. In IFetchImpl.cpp, in function "memoryResponse", the reply for a >>>> "Probe" is always "ProbedNotPresent". Can you please clarify the reason >>>> for this. (I think that since this is the IFetch component, it does not >>>> cache anything, and so no probe will hit. However, then why does this >>>> component even get Invalidate or Downgrade requests?) >> >> >> Probe messages are used to maintain coherence between the L1 I and L1 D >> caches. Basically, if an instruction access misses in L1 I and L2, a probe >> message is sent to L1D to check if the line is present there. The SPARC >> archictecture doesn't actually require the I and D caches to be coherent. >> However, our DSM coherence protocol requires this (the Probe works around a >> specific case: when a cache block is not present in L1I or L2, but present >> and dirty in L1D. This case is rare, but does happen. Without Probes, this >> case would result an error in our coherence protocol). >> >> As you noted, the IFetch component doesn't cache anything, so it always >> replies with ProbedNotPresent when it receives a Probe. The in-order core >> also has no need for Invalidate and Downgrade messages. (The out-of-order >> core does use these messages to enforce multiprocessor memory ordering >> constraints in the load-store queue). The only reason we send these >> messages to the IFetch is to simplify the cache code - a cache has no idea >> if it is the top level of the cache heirarchy, so all the caches pass these >> messages up, and the IFetch component starts the response propagation back >> down the hierarchy. >> >>>> >>>> In fact, can you please clarify the communication that goes on between >>>> the L1-L2 caches, and the L1i-IFetch and the L1d-Execute ? >>>> >>>> 2. In ExecuteImpl.cpp, in class ExecuteStateImpl, what is the exact >>>> meaning of 'theIsIssued', 'theIsInitiated', 'theIsPerformed' and >>>> 'theIsComplete'. To me, the first two seem similar to each other. Whats >>>> the difference between them? The last two also seem similar to each >>>> other. >>>> >> >> I'm a bit rusty on the in-order core (everyone here is using TraceFlex or >> the out-of-order simulator now), but from a quick look at the code: >> >> issue() is called at the time an instruction is received by the Execute >> component. This tells the InorderSimicsFeeder component to >> execute the instruction. For non memory instructions, this >> causes the instruction to be marked as "performed". For memory >> instructions, nothing happens yet. >> >> initiate() is called for memory operations when they are sent to the >> memory system (L1D). It is used for bookkeeping (so a memory >> operation is not sent twice). >> >> perform() is called at the moment in time that a memory operation should >> take effect, that is, the moment where a load is bound to a >> value and a store value becomes visible to other processors in >> the system. It is usually called when a reply returns from the >> memory system. This function also causes the >> InorderSimicsFeeder to trigger the load or store in Simics. >> >> complete() is called when an instruction is done, and tells the >> InorderSimicsFeeder that it can forget the instruction and move >> on to the next one. >> >> Hope that helps. >> >> Regards, >> -Tom Wenisch >> >>>> >>>> Thanks, >>>> - Mrinal >>>> _______________________________________________ >>>> SimFlex mailing list >>>> [email protected] >>>> https://sos.ece.cmu.edu/mailman/listinfo/simflex >>>> SimFlex web page: http://www.ece.cmu.edu/~simflex >>> >>> _______________________________________________ >>> SimFlex mailing list >>> [email protected] >>> https://sos.ece.cmu.edu/mailman/listinfo/simflex >>> SimFlex web page: http://www.ece.cmu.edu/~simflex >>> >> _______________________________________________ >> SimFlex mailing list >> [email protected] >> https://sos.ece.cmu.edu/mailman/listinfo/simflex >> SimFlex web page: http://www.ece.cmu.edu/~simflex > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex > From twenisch at ece.cmu.edu Sat Sep 16 14:45:39 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Sat Sep 16 14:45:43 2006 Subject: [Simflex] How to detect haps? In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Mrinal, On Sat, 16 Sep 2006, Mrinal Nath wrote: > Hi Tom, > Thanks for the reply. I was able to write a function similar to > EndOfParallelTracker (in BreakpointTracker.cpp) and get it to execute when my > hap occurs. > > Now I have another problem: I want to access member functions of > InorderSimicsFeeder or SimicsTracer from the above function that I am talking > about. But I don't know the "name" of the object/pointer of the > InorderSimicsFeeder component class. (e.g. the EndOfParallelTracker accesses > theFlexus->terminateSimulation). Is there some handle like "theFeeder" or > "theFlexus->theFeeder" or something similar by which I can access a member > function of InorderSimicsFeeder? > > If there is no such name, then how can I go about achieving this? There is no global name. You have two choices: 1) Add ports and channels to have the MagicBreak component talk to the InorderSimicsFeeder through Flexus' wiring, just like other communications among components. You can have the MagicBreak component pass an object in to your Tracker to allow it to pass data to the MagicBreak, which can then send it on its way through the wiring. There are plenty of examples of using ports and wiring throughout the Flexus code 2) Add a global object that acts as the connection between your Tracker and the code in the Feeder. On simulator startup (e.g., in initialize(), both your Tracker and the InorderSimicsFeeder objects can register themselves with this global object by passing in pointers to themselves. This global object can then allow the two pieces of code to talk to one another. The MemoryMap and TraceTracker components work sort of like this. Of these two solutions (1) is superior, as it is a clearer design and more flexible (you can change what is connected to what in the wiring). (2) is more of a hack, but lets you get any two pieces of code to talk, which is useful if your code is buried deep inside a component. Regards, -Tom Wenisch Computer Architecture Lab Carnegie Mellon University > > Thanks :) > - Mrinal > > Thomas Wenisch wrote: >> Hi Mrinal, >> >> Take a look at the MagicBreak component to see examples of how to catch >> haps (including the Core_Magic_Instruction hap). >> >> Best Regards, >> -Tom Wenisch >> Computer Architecture Lab >> Carnegie Mellon University >> >> On Fri, 15 Sep 2006, Mrinal Nath wrote: >> >>> Hi, >>> I had a question related to using Simics 'haps' within the Flexus >>> simulator. >>> >>> I have created a magic breakpoint (sparc) so that Simics will break the >>> simulation when this particular magic instruction is executed by Simics. I >>> want Flexus to know that this particular magic instruction has been seen >>> by Simics and therefore execute some particular function. How can I go >>> about achieving this? >>> >>> Thanks >>> - Mrinal >>> _______________________________________________ >>> SimFlex mailing list >>> [email protected] >>> https://sos.ece.cmu.edu/mailman/listinfo/simflex >>> SimFlex web page: http://www.ece.cmu.edu/~simflex >>> >> _______________________________________________ >> SimFlex mailing list >> [email protected] >> https://sos.ece.cmu.edu/mailman/listinfo/simflex >> SimFlex web page: http://www.ece.cmu.edu/~simflex > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex > From mrinal at ece.umn.edu Sun Sep 17 00:35:07 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Sun Sep 17 00:35:17 2006 Subject: [Simflex] How to detect haps? In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Tom, Thanks for your suggestions. I am trying to follow suggestion (1) below by adding ports to the MagicBreak and InorderSimicsFeeder components. I added the following line to MagicBreak.hpp (in COMPONENT_INTERFACE) section: PORT( PushOutput, unsigned int, MONIT_HapInfoOut ) I have added corresponding ports in the InorderSimicsFeeder, and connected these ports in the CMPFlex/wiring.cpp file. With just these changes, the code compiles successfully. Now, in MagicBreakImpl.cpp, I am trying to write a function that will push data through the output port that I added above: static void sendMONIT_HapInfo(unsigned int anIndex) { FLEXUS_CHANNEL( MONIT_HapInfoOut ) << anIndex; } However, I am getting the following compilation errors after adding the above function: ######### start errors ######## MagicBreakImpl.cpp: In static member function `static void nMagicBreak::MagicBreakComponent::sendMONIT_HapInfo(unsigned int)': /project/zhai-project01/mrinal/CVS/Simulators/flexus_2.0/core/component.hpp:155: error: invalid use of member ` Flexus::Core::FlexusComponentBase<nMagicBreak::MagicBreakComponent, MagicBreakConfiguration, MagicBreakInterface>::jump_table_' in static member function MagicBreakImpl.cpp:247: error: from this location /project/zhai-project01/mrinal/CVS/Simulators/flexus_2.0/core/component.hpp:155: error: invalid use of member ` Flexus::Core::FlexusComponentBase<nMagicBreak::MagicBreakComponent, MagicBreakConfiguration, MagicBreakInterface>::jump_table_' in static member function MagicBreakImpl.cpp:247: error: from this location MagicBreakImpl.cpp:247: error: cannot call member function `Flexus::Core::index_t Flexus::Core::FlexusComponent::flexusIndex() const' without object make[11]: *** [MagicBreakImpl.v9_iface_gcc_o] Error 1 ######### end errors ######## I am unable to understand what this error means. Could you please let me know how to go about fixing this error. Have I made some mistake in adding the port to MagicBreak component ? I had another question: Is it possible to call the FLEXUS_CHANNEL(MONIT_HapInfoOut) << anIndex; in another class (for e.g. the in the class like EndOfParallelTracker in BreakpointTracker.cpp ? I tried doing that, but was not able to get it to compile, so I thought that we have to call the 'FLEXUS_CHANNEL(aPort)' only inside the component that has the port 'aPort'. Is my understanding correct? Thanks for your help Regards - Mrinal Thomas Wenisch wrote: > Hi Mrinal, > > On Sat, 16 Sep 2006, Mrinal Nath wrote: > >> Hi Tom, >> Thanks for the reply. I was able to write a function similar to >> EndOfParallelTracker (in BreakpointTracker.cpp) and get it to execute >> when my hap occurs. >> >> Now I have another problem: I want to access member functions of >> InorderSimicsFeeder or SimicsTracer from the above function that I am >> talking about. But I don't know the "name" of the object/pointer of >> the InorderSimicsFeeder component class. (e.g. the >> EndOfParallelTracker accesses theFlexus->terminateSimulation). Is >> there some handle like "theFeeder" or "theFlexus->theFeeder" or >> something similar by which I can access a member function of >> InorderSimicsFeeder? >> >> If there is no such name, then how can I go about achieving this? > > > There is no global name. You have two choices: > > 1) Add ports and channels to have the MagicBreak component talk to the > InorderSimicsFeeder through Flexus' wiring, just like other > communications among components. You can have the MagicBreak component > pass an object in to your Tracker to allow it to pass data to the > MagicBreak, which can then send it on its way through the wiring. There > are plenty of examples of using ports and wiring throughout the Flexus code > > 2) Add a global object that acts as the connection between your Tracker > and the code in the Feeder. On simulator startup (e.g., in > initialize(), both your Tracker and the InorderSimicsFeeder objects can > register themselves with this global object by passing in pointers to > themselves. This global object can then allow the two pieces of code to > talk to one another. The MemoryMap and TraceTracker components work > sort of like this. > > Of these two solutions (1) is superior, as it is a clearer design and > more flexible (you can change what is connected to what in the wiring). > (2) is more of a hack, but lets you get any two pieces of code to talk, > which is useful if your code is buried deep inside a component. > > Regards, > -Tom Wenisch > Computer Architecture Lab > Carnegie Mellon University > > From twenisch at ece.cmu.edu Sun Sep 17 01:45:17 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Sun Sep 17 01:45:24 2006 Subject: [Simflex] How to detect haps? In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Mrinal, On Sat, 16 Sep 2006, Mrinal Nath wrote: > Hi Tom, > Thanks for your suggestions. I am trying to follow suggestion (1) below by > adding ports to the MagicBreak and InorderSimicsFeeder components. > > I added the following line to MagicBreak.hpp (in COMPONENT_INTERFACE) > section: > > PORT( PushOutput, unsigned int, MONIT_HapInfoOut ) > > I have added corresponding ports in the InorderSimicsFeeder, and connected > these ports in the CMPFlex/wiring.cpp file. > > With just these changes, the code compiles successfully. > > Now, in MagicBreakImpl.cpp, I am trying to write a function that will push > data through the output port that I added above: > > static void sendMONIT_HapInfo(unsigned int anIndex) { > FLEXUS_CHANNEL( MONIT_HapInfoOut ) << anIndex; > } The problem here is that you have declared this function static. It needs to be a regular member function, because FLEXUS_CHANNEL needs to refer to the component object (*this) to figure out which other component it is connected to. > > > However, I am getting the following compilation errors after adding the above > function: < snip errors > > > I am unable to understand what this error means. Could you please let me know > how to go about fixing this error. Have I made some mistake in adding the > port to MagicBreak component ? > > I had another question: Is it possible to call the > FLEXUS_CHANNEL(MONIT_HapInfoOut) << anIndex; > in another class (for e.g. the in the class like EndOfParallelTracker in > BreakpointTracker.cpp ? No, because it needs the component object. The FLEXUS_CHANNEL macro only works within member functions of the component. > > I tried doing that, but was not able to get it to compile, so I thought that > we have to call the 'FLEXUS_CHANNEL(aPort)' only inside the component that > has the port 'aPort'. Is my understanding correct? Your understanding is correct. So, again you have two choices to get your non-component (namespace scope) code to talk to a channel. 1) Create an interface class that your component inherits from, and then pass a pointer of this interface type to your Tracker object. (warning - uncompiled code, may contain errors) In MONIT.hpp: struct MONIT_Interface { virtual void sendMONIT_HapInfo(unsigned int) = 0; virtual ~MONIT_Interface() {} }; In breakpoint_tracker.hpp: #include "MONIT.hpp" struct MONIT_Tracker : public BreakpointTracker { /*...*/ virtual void setMONIT_Interface( MONIT_Interface * ) { /*...*/ } }; In MagicBreakImpl.cpp #include "MONIT.hpp" /*...*/ class FLEXUS_COMPONENT(MagicBreak), public MONIT_Interface { /*^^Inherit from interface */ void sendMONIT_HapInfo(unsigned int) { /*...*/ } void initialize() { /* ... */ theMONITTracker.setMONIT_Interface( this ) ; /* ... */ } /*...*/ }; Obviously, I have omitted tons of details, but the above code should give you the basic idea. 2) Wrap the call to sendMONIT_HapInfo into a boost::function<> object using the boost::lambda or boost::bind library and pass the function object to your tracker. I personally think this solution is more elegant (it takes less code), but it means you'll have to spend some time looking at the Boost.Function and Boost.Bind library documentation on www.boost.org. I think the most brief example of this solution is in the DecoupledFeeder component. See if you can understand how the toL1D() function is wrapped up and passed from the DecoupledFeederComponent to the SimicsTracerManager object (see DecoupledFeederImpl.cpp constructor at line 85). Regards, -Tom Wenisch Computer Architecture Lab Carnegie Mellon University > > Thanks for your help > Regards > - Mrinal > > > > Thomas Wenisch wrote: >> Hi Mrinal, >> >> On Sat, 16 Sep 2006, Mrinal Nath wrote: >> >>> Hi Tom, >>> Thanks for the reply. I was able to write a function similar to >>> EndOfParallelTracker (in BreakpointTracker.cpp) and get it to execute when >>> my hap occurs. >>> >>> Now I have another problem: I want to access member functions of >>> InorderSimicsFeeder or SimicsTracer from the above function that I am >>> talking about. But I don't know the "name" of the object/pointer of the >>> InorderSimicsFeeder component class. (e.g. the EndOfParallelTracker >>> accesses theFlexus->terminateSimulation). Is there some handle like >>> "theFeeder" or "theFlexus->theFeeder" or something similar by which I can >>> access a member function of InorderSimicsFeeder? >>> >>> If there is no such name, then how can I go about achieving this? >> >> >> There is no global name. You have two choices: >> >> 1) Add ports and channels to have the MagicBreak component talk to the >> InorderSimicsFeeder through Flexus' wiring, just like other communications >> among components. You can have the MagicBreak component pass an object in >> to your Tracker to allow it to pass data to the MagicBreak, which can then >> send it on its way through the wiring. There are plenty of examples of >> using ports and wiring throughout the Flexus code >> >> 2) Add a global object that acts as the connection between your Tracker >> and the code in the Feeder. On simulator startup (e.g., in initialize(), >> both your Tracker and the InorderSimicsFeeder objects can register >> themselves with this global object by passing in pointers to themselves. >> This global object can then allow the two pieces of code to talk to one >> another. The MemoryMap and TraceTracker components work sort of like this. >> >> Of these two solutions (1) is superior, as it is a clearer design and more >> flexible (you can change what is connected to what in the wiring). (2) is >> more of a hack, but lets you get any two pieces of code to talk, which is >> useful if your code is buried deep inside a component. >> >> Regards, >> -Tom Wenisch >> Computer Architecture Lab >> Carnegie Mellon University >> >> > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex > From mrinal at ece.umn.edu Mon Sep 18 05:13:46 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Mon Sep 18 05:14:05 2006 Subject: [Simflex] How to detect haps? In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Tom, Thank a lot for your suggestions. Declaring the function 'static' was indeed the root of all trouble. Also, I was able to use the boost::bind and boost::function<>. That seems to be a useful way of invoking functions of another class when we don't have a handle (object or pointer) on that class. Thanks much ! - Mrinal Thomas Wenisch wrote: > Hi Mrinal, > > On Sat, 16 Sep 2006, Mrinal Nath wrote: > >> Hi Tom, >> Thanks for your suggestions. I am trying to follow suggestion (1) >> below by adding ports to the MagicBreak and InorderSimicsFeeder >> components. >> >> I added the following line to MagicBreak.hpp (in COMPONENT_INTERFACE) >> section: >> >> PORT( PushOutput, unsigned int, MONIT_HapInfoOut ) >> >> I have added corresponding ports in the InorderSimicsFeeder, and >> connected these ports in the CMPFlex/wiring.cpp file. >> >> With just these changes, the code compiles successfully. >> >> Now, in MagicBreakImpl.cpp, I am trying to write a function that will >> push data through the output port that I added above: >> >> static void sendMONIT_HapInfo(unsigned int anIndex) { >> FLEXUS_CHANNEL( MONIT_HapInfoOut ) << anIndex; >> } > > > The problem here is that you have declared this function static. It > needs to be a regular member function, because FLEXUS_CHANNEL needs to > refer to the component object (*this) to figure out which other > component it is connected to. > >> >> >> However, I am getting the following compilation errors after adding >> the above function: > > > < snip errors > > >> >> I am unable to understand what this error means. Could you please let >> me know how to go about fixing this error. Have I made some mistake in >> adding the port to MagicBreak component ? >> >> I had another question: Is it possible to call the >> FLEXUS_CHANNEL(MONIT_HapInfoOut) << anIndex; >> in another class (for e.g. the in the class like EndOfParallelTracker >> in BreakpointTracker.cpp ? > > > No, because it needs the component object. The FLEXUS_CHANNEL macro > only works within member functions of the component. > >> >> I tried doing that, but was not able to get it to compile, so I >> thought that we have to call the 'FLEXUS_CHANNEL(aPort)' only inside >> the component that has the port 'aPort'. Is my understanding correct? > > > Your understanding is correct. So, again you have two choices to get > your non-component (namespace scope) code to talk to a channel. > > 1) Create an interface class that your component inherits from, and then > pass a pointer of this interface type to your Tracker object. > > (warning - uncompiled code, may contain errors) > > In MONIT.hpp: > > struct MONIT_Interface { > virtual void sendMONIT_HapInfo(unsigned int) = 0; > virtual ~MONIT_Interface() {} > }; > > In breakpoint_tracker.hpp: > > #include "MONIT.hpp" > struct MONIT_Tracker : public BreakpointTracker { > /*...*/ > virtual void setMONIT_Interface( MONIT_Interface * ) { /*...*/ } }; > > In MagicBreakImpl.cpp > > #include "MONIT.hpp" > /*...*/ > class FLEXUS_COMPONENT(MagicBreak), public MONIT_Interface { > /*^^Inherit from interface */ > void sendMONIT_HapInfo(unsigned int) { /*...*/ } > void initialize() { > /* ... */ > theMONITTracker.setMONIT_Interface( this ) ; > /* ... */ > } > /*...*/ > }; > > Obviously, I have omitted tons of details, but the above code should > give you the basic idea. > > > 2) Wrap the call to sendMONIT_HapInfo into a boost::function<> object > using the boost::lambda or boost::bind library and pass the function > object to your tracker. > > I personally think this solution is more elegant (it takes less code), > but it means you'll have to spend some time looking at the > Boost.Function and Boost.Bind library documentation on www.boost.org. I > think the most brief example of this solution is in the DecoupledFeeder > component. See if you can understand how the toL1D() function is > wrapped up and passed from the DecoupledFeederComponent to the > SimicsTracerManager object (see DecoupledFeederImpl.cpp constructor at > line 85). > > Regards, > -Tom Wenisch > Computer Architecture Lab > Carnegie Mellon University > >> >> Thanks for your help >> Regards >> - Mrinal >> >> >> >> Thomas Wenisch wrote: >> >>> Hi Mrinal, >>> >>> On Sat, 16 Sep 2006, Mrinal Nath wrote: >>> >>>> Hi Tom, >>>> Thanks for the reply. I was able to write a function similar to >>>> EndOfParallelTracker (in BreakpointTracker.cpp) and get it to >>>> execute when my hap occurs. >>>> >>>> Now I have another problem: I want to access member functions of >>>> InorderSimicsFeeder or SimicsTracer from the above function that I >>>> am talking about. But I don't know the "name" of the object/pointer >>>> of the InorderSimicsFeeder component class. (e.g. the >>>> EndOfParallelTracker accesses theFlexus->terminateSimulation). Is >>>> there some handle like "theFeeder" or "theFlexus->theFeeder" or >>>> something similar by which I can access a member function of >>>> InorderSimicsFeeder? >>>> >>>> If there is no such name, then how can I go about achieving this? >>> >>> >>> >>> There is no global name. You have two choices: >>> >>> 1) Add ports and channels to have the MagicBreak component talk to >>> the InorderSimicsFeeder through Flexus' wiring, just like other >>> communications among components. You can have the MagicBreak >>> component pass an object in to your Tracker to allow it to pass data >>> to the MagicBreak, which can then send it on its way through the >>> wiring. There are plenty of examples of using ports and wiring >>> throughout the Flexus code >>> >>> 2) Add a global object that acts as the connection between your >>> Tracker and the code in the Feeder. On simulator startup (e.g., in >>> initialize(), both your Tracker and the InorderSimicsFeeder objects >>> can register themselves with this global object by passing in >>> pointers to themselves. This global object can then allow the two >>> pieces of code to talk to one another. The MemoryMap and >>> TraceTracker components work sort of like this. >>> >>> Of these two solutions (1) is superior, as it is a clearer design and >>> more flexible (you can change what is connected to what in the >>> wiring). (2) is more of a hack, but lets you get any two pieces of >>> code to talk, which is useful if your code is buried deep inside a >>> component. >>> >>> Regards, >>> -Tom Wenisch >>> Computer Architecture Lab >>> Carnegie Mellon University >>> >>> >> _______________________________________________ >> SimFlex mailing list >> [email protected] >> https://sos.ece.cmu.edu/mailman/listinfo/simflex >> SimFlex web page: http://www.ece.cmu.edu/~simflex >> > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex From ioana at eecg.toronto.edu Wed Sep 20 11:59:25 2006 From: ioana at eecg.toronto.edu (Ioana Burcea) List-Post: [email protected] Date: Wed Sep 20 16:19:24 2006 Subject: [Simflex] cpu-switch-time in prepare-test-app.simics Message-ID: <[email protected]> Hi Tom, In "prepare-test-app.simics", before saving the checkpoint "flexus-test-warmup", you use cpu-switch-time command. Could you please tell me why that command is needed? I tried to use something similar in one of my scripts and I got a simics error, when I tried to use the checkpoint for some timing simulation. The error message looks smth like this: ================================ *** ASSERTION ERROR: >> Cpu switch in clock cycle mode, should not happen << in line 1002 of file '/home/mp/simics-2.2.19/src/core/common/event.c' with RCSID '@(#) $Id: event.c,v 38.0.2.19 2005/06/08 17:10:23 mattias Exp $' Please report this. Simics will now self-signal an abort. (*** Simics ***) Simics getting shaky, switching to 'safe' mode. (*** Simics ***) Simics (main thread) received an abort signal, probably an assertion. ================================== Getting rid of that cpu-switch-time command just before I created my checkpoint got rid of the error. Do you have any insight about what's going on? Thank you in advance. Your time and help is appreciated. Ioana From twenisch at ece.cmu.edu Thu Sep 21 14:00:52 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Thu Sep 21 14:00:57 2006 Subject: [Simflex] cpu-switch-time in prepare-test-app.simics In-Reply-To: <[email protected]> References: <[email protected]> Message-ID: <[email protected]> Hi Ioanna, the cpu-switch-time command changes the Simics simulation quantum; that is, the number of steps Simics will simulate on one CPU before switching to the next. The higher the quantum, the faster Simics runs (up to about 1000 or so), but the interleaving of memory operations across CPUs is constrained by the quantum, so the simulation may be less accurate (relative to memory ordering on a real machine). Simics does not like it if you change this setting at certain points in the simulation, but I'm not sure exactly what conditions cause it to fail. TraceFlex controls this setting automatically (it sets it to the value of the cfg.SimicsQuantum parameter; we have experimentally determined that 100 gives the best Simics performance trade-off). When running OoO simulations, the setting is irrelevant, because the out-of-order core controls the advancement of Simics. For in-order simulation, we recommend setting this to 1, to get the correct interleaving of instructions across CPUs. However, you want to set this back to ~1000 if you are going to run in Simics w/o Flexus, to accelerate simulation. You can also edit this setting directly in checkpoints, by changing the value of cpu_switch_time in the sim object. Regards, -Tom Wenisch On Wed, 20 Sep 2006, Ioana Burcea wrote: > Hi Tom, > > In "prepare-test-app.simics", before saving the checkpoint > "flexus-test-warmup", you use cpu-switch-time command. Could you please tell > me why that command is needed? > > I tried to use something similar in one of my scripts and I got a simics > error, when I tried to use the checkpoint for some timing simulation. The > error message looks smth like this: > > ================================ > *** ASSERTION ERROR: >> Cpu switch in clock cycle mode, should not happen << > in line 1002 > of file '/home/mp/simics-2.2.19/src/core/common/event.c' > with RCSID '@(#) $Id: event.c,v 38.0.2.19 2005/06/08 17:10:23 mattias Exp > $' > Please report this. > Simics will now self-signal an abort. > (*** Simics ***) Simics getting shaky, switching to 'safe' mode. > (*** Simics ***) Simics (main thread) received an abort signal, probably an > assertion. > ================================== > > Getting rid of that cpu-switch-time command just before I created my > checkpoint got rid of the error. > > Do you have any insight about what's going on? > > Thank you in advance. Your time and help is appreciated. > Ioana > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex > From mrinal at ece.umn.edu Tue Sep 26 05:12:05 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Tue Sep 26 05:12:16 2006 Subject: [Simflex] Accounting for stall cycles In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi, I had a question about how stalls are being accounted for load/store instructions. Looking at InorderSimicsFeeder/SimicsTracer, it seems that "real_hier_operate" is calculating some value of stall cycles (by calling theCycleManager->reconcileTime()) to be returned to Simics. Can you please explain what exactly reconcileTime() is doing. However, my main question is: this stall value is being calculated even *before* the instruction goes into the IFetch (for fetches) or Execute (for load/store/atomic) components. It is these components that request for the instruction or data word from the L1I or L1D respectively. Only then can it be know if the access is a hit or a miss in the L1 caches and appropriate stall value calculated. In ExecuteImpl.cpp, in the ExecuteMemReply port, several types of stalls are being accounted for. I think that these are the 'actual' values based on where in the memory hierarchy the requested word is found (L1 or L2 or main memory). (Am I correct?) So there seems to be some decoupling or disconnect between what stall value is being returned to Simics by the real_hier_operate() function, and the actual stalls being accounted/simulated based on cache misses in ExecuteMemReply(). Can you please explain what is going on here and how the two stall values can be different? Thanks - Mrinal From twenisch at ece.cmu.edu Wed Sep 27 01:34:54 2006 From: twenisch at ece.cmu.edu (Thomas Wenisch) List-Post: [email protected] Date: Wed Sep 27 01:35:00 2006 Subject: [Simflex] Accounting for stall cycles In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]> Message-ID: <[email protected]> Hi Mrinal, First, let me apologize for my brevity, as I am travelling. I may be slow to respond over the next week. On Tue, 26 Sep 2006, Mrinal Nath wrote: > Hi, > > I had a question about how stalls are being accounted for load/store > instructions. > > Looking at InorderSimicsFeeder/SimicsTracer, it seems that > "real_hier_operate" is calculating some value of stall cycles (by calling > theCycleManager->reconcileTime()) to be returned to Simics. > > Can you please explain what exactly reconcileTime() is doing. We only synchronize the cycle count in Simics and the cycle count in Flexus at memory instructions. reconcileTime() keeps Simics' notion of time and Flexus' notion of time synchronized while taking into account non memory instructions. One important detail to note is that we advance 2 cycles in Simics for every cycle in Flexus (it is not possible to guarantee a 1:1 ratio of Simics to Flexus cycles in MP simulations because Simics simulates CPUs in round-robin fashion, while Flexus advances the entire simulation by a cycle atomically. We chose to model a 2:1 cycle ratio because it is easy to maintain; reconcileTime() maintains this ratio). > > However, my main question is: this stall value is being calculated even > *before* the instruction goes into the IFetch (for fetches) or Execute (for > load/store/atomic) components. It is these components that request for the > instruction or data word from the L1I or L1D respectively. Only then can it > be know if the access is a hit or a miss in the L1 caches and appropriate > stall value calculated. > > In ExecuteImpl.cpp, in the ExecuteMemReply port, several types of stalls are > being accounted for. I think that these are the 'actual' values based on > where in the memory hierarchy the requested word is found (L1 or L2 or main > memory). (Am I correct?) > > So there seems to be some decoupling or disconnect between what stall value > is being returned to Simics by the real_hier_operate() function, and the > actual stalls being accounted/simulated based on cache misses in > ExecuteMemReply(). > > Can you please explain what is going on here and how the two stall values can > be different? The key detail to know here is how the timing_model interface in Simics works. When we report a non-zero stall time to Simics, after the specified number of cycles has elapsed, Simics calls us *again* to see if we should stall further. When the InorderSimicsFeeder knows it has to stall a CPU before even beginning a memory operation (because reconcileTime() indicates Flexus is ahead of Simics), we return a stall value > 1. However, while a memory operation is pending, we return k_call_me_next_cycle (== 1) which tells Simics that the currently-pending operation is not done yet, but we don't know how much longer it will take. Simics will keep calling us every cycle until Flexus has determined that the memory operation is complete. Regards, -Tom Wenisch > > Thanks > - Mrinal > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex > From mrinal at ece.umn.edu Wed Sep 27 18:19:40 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Wed Sep 27 18:20:14 2006 Subject: [Simflex] Question about L1 cache Message-ID: <[email protected]> Hi, I wanted to change the L1 caches to be write-through in CMPFlex. I think that any changes that I may need to make will go in CacheControllerImpl.cpp. ( PiranhaCacheControllerImpl also uses BaseCacheControllerImpl, and the piranha is used only for L2 cache, so I can't change the BaseCacheControllerImpl... is this correct? ) Any help about where I should start changing the code will be very much appreciated. Thanks a lot - Mrinal From mrinal at ece.umn.edu Wed Sep 27 22:11:23 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Wed Sep 27 22:11:31 2006 Subject: [Simflex] What types of memory messages are used in CMPFlex? Message-ID: <[email protected]> Hi, I was going through the cache code and in BaseCacheControllerImpl::handleRequestMessage, I noticed that there is a piece of code: if(( msg->type() == MemoryMessage::PrefetchReadNoAllocReq || msg->type() == MemoryMessage::PrefetchReadAllocReq ) && has_maf_entry) { // consider a hit in the MAF to be similar to a hit in the // array - redundant for both msg->type() = MemoryMessage::PrefetchReadRedundant; return kSend; } I could *not* find (by grep-ing) where a memory message of type PrefetchReadNoAllocReq or PrefetchReadAllocReq is *created*. Nor is there any place where the type of a memory message is *set* to one of these two values. However, there are several places where the type of a memory message is compared against one or both of these values (like in the code above). Can someone tell me why these two types are being used? It seems that these types are useless, since no memory message of these types exists ! Also, can someone tell which types are actually used in the code related to CMPFlex ? Thanks - Mrinal From mrinal at ece.umn.edu Fri Sep 29 03:02:55 2006 From: mrinal at ece.umn.edu (Mrinal Nath) List-Post: [email protected] Date: Fri Sep 29 03:03:05 2006 Subject: [Simflex] Whats is TraceTracker used for? Message-ID: <[email protected]> Hi, In the CacheControllerImpl, there is a lot of code related to 'theTraceTracker'. I couldn't figure out what that component is doing. Also, although this component is in the "required components" list in the make file for CMPFlex, I could not find any reference to it in the wiring.cpp file for CMPFlex. So how is this component being used in CMPFlex? Thanks - Mrinal From ssomogyi at ece.cmu.edu Fri Sep 29 15:00:30 2006 From: ssomogyi at ece.cmu.edu (Stephen Somogyi) List-Post: [email protected] Date: Fri Sep 29 15:00:36 2006 Subject: [Simflex] What types of memory messages are used in CMPFlex? In-Reply-To: <[email protected]> References: <[email protected]> Message-ID: <pine.lnx.4.53l-ece.cmu.edu.0609291402200.16...@aprile.ece.cmu.edu> Hi Mrinal, MemoryMessage is common to all Flexus simulators, and as such some simulators will never encounter certain messages. For example, ReturnReq is only used in CMP simulators, and Invalidate and Downgrade will never be observed in uniprocessor simuations. By keeping the Cache code common and up to date with all messages, we can easily rearrange components when we wish to simulate a different system. In general, the code we distribute in Flexus releases is suitable for simulating ordinary systems. However, different groups at CMU are involved in architecture research, and the code/components associated with this research is not typically included in the release distribution. For example, in Temporal Streaming and Spatial Memory Streaming, we fetch blocks into a node's local cache hierarchy through PrefetchReq's. We have not included the component that actually sits within the hierarchy (e.g., between L1d and L2) and issues prefetches, but we do include the necessary support from the Caches. With respect to which messages are used in CMPFlex, different messages will appear on different channels. Simply enable debugging output (with iface debugging) to see which messages are sent in/out of which ports. Stephen On Wed, 27 Sep 2006, Mrinal Nath wrote: > Hi, > I was going through the cache code and in > BaseCacheControllerImpl::handleRequestMessage, I noticed that there is a > piece of code: > > > if(( msg->type() == MemoryMessage::PrefetchReadNoAllocReq || > msg->type() == MemoryMessage::PrefetchReadAllocReq ) && > has_maf_entry) > { > // consider a hit in the MAF to be similar to a hit in the > // array - redundant for both > msg->type() = MemoryMessage::PrefetchReadRedundant; > return kSend; > } > > > I could *not* find (by grep-ing) where a memory message of type > PrefetchReadNoAllocReq or PrefetchReadAllocReq is *created*. Nor is > there any place where the type of a memory message is *set* to one of > these two values. > > However, there are several places where the type of a memory message is > compared against one or both of these values (like in the code above). > > Can someone tell me why these two types are being used? It seems that > these types are useless, since no memory message of these types exists ! > > Also, can someone tell which types are actually used in the code related > to CMPFlex ? > > Thanks > - Mrinal > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex > From ssomogyi at ece.cmu.edu Fri Sep 29 15:20:11 2006 From: ssomogyi at ece.cmu.edu (Stephen Somogyi) List-Post: [email protected] Date: Fri Sep 29 15:20:22 2006 Subject: [Simflex] Whats is TraceTracker used for? In-Reply-To: <[email protected]> References: <[email protected]> Message-ID: <pine.lnx.4.53l-ece.cmu.edu.0609291501090.16...@aprile.ece.cmu.edu> Hi Mrinal, While Flexus' component-based design is powerful and allows simulators to be reconfigured easily, it makes it difficult for a single piece of code to observe events that occur in different other components. The TraceTracker is a global object that receives notifications of interesting events (e.g., cache hits and misses). It is notified about events on all nodes and for all cache levels. The technical reason why TraceTracker must be in the makefile for CMPFlex (even if you are not using it) is that other components must link to the 'theTraceTracker' object. If you remove TraceTracker from the makefile, you will get a linker error. If you think TraceTracker could be useful in your research, simply add code to the appropriate functions in TraceTracker.cpp. Stephen On Fri, 29 Sep 2006, Mrinal Nath wrote: > Hi, > In the CacheControllerImpl, there is a lot of code related to > 'theTraceTracker'. I couldn't figure out what that component is doing. > > Also, although this component is in the "required components" list in > the make file for CMPFlex, I could not find any reference to it in the > wiring.cpp file for CMPFlex. > > So how is this component being used in CMPFlex? > > Thanks > - Mrinal > _______________________________________________ > SimFlex mailing list > [email protected] > https://sos.ece.cmu.edu/mailman/listinfo/simflex > SimFlex web page: http://www.ece.cmu.edu/~simflex >
