stephane eranian wrote: > On Mon, Dec 7, 2009 at 10:46 PM, Corey Ashford > <cjash...@linux.vnet.ibm.com> wrote: >> Hi Stephane, >> >> stephane eranian wrote: >>> On Fri, Dec 4, 2009 at 11:16 PM, Corey Ashford >>> <cjash...@linux.vnet.ibm.com> wrote: >>> >>>> I assume this is supposed to be >>>> .uname = "CORE_SELF",\ >>>> >>>>> .udesc = "This core",\ >>>>> .ucode = 0x40\ >>>>> },\ >>>>> { .uname = "BOTH_CORES",\ >>>> and >>>> .uname = "CORE_BOTH",\ >>>> >>>>> .udesc = "Both cores",\ >>>>> .ucode = 0xc0\ >>>>> } >>>>> >>> Yes. >>> >>> >>>>> In this particular case, a reasonable default would be >>>>> >>>>> L2_LD:ANY:MESI:CORE_SELF:u=1:k=0:i=0:e=0:c=0 >>>>> >>>>> I think the only reasonable approach would be for the >>>>> tool to iterate over all the attributes and query 'default' >>>>> information. So here, it would return: >>>>> >>>>> M: is_dfl=0 >>>>> E: is_dfl=0 >>>>> S: is_dfl=0 >>>>> I: is_dfl=0 >>>>> MESI: is_dfl=1 value=0xf (unit mask value) >>>>> CORE_BOTH: is_dfl=0 >>>>> CORE_SELF: is_dfl=1 >>>>> u: is_dfl=1 value=1 >>>>> k: is_dfl=0 >>>>> i: is_dfl=0 >>>>> e: is_dfl=0 >>>>> c: is_dfl=0 >>>> Just so I'm certain I understand what you are saying, if I specify >>>> >>>> L2_LD:MESI:M=0 >>>> >>>> would that be an error (because M=0 conflicts with MESI) ? >>>> >>> I assume you mean M as in Modified, i.e,, from MESI. In this >>> case, you would get an error because MESI are managed as >>> unit masks, not modifiers. You'd get an error because there is >>> no modifier called M. >>> >>> But going back to your example: >>> L2_LD:MESI:M >>> >>> This would be legal because MESI bits can be combined. That would >>> be a stupid combination because you would end up measuring MESI. >>> The library would have to ensure that there is either at least one >>> unit mask set per group (here the group is M, E, S, I) or it would pick >>> the default (here MESI). >> I think I was a bit confused because there was no group description for >> INTEL_CORE_MESI_UMASKS. >> >> I see how it works for unit masks, but what about modifiers with values? >> >> Let's say I have a group called DFL_GROUP which, as one of the things it >> does >> sets an integer modifier x to 0. Could I do this: >> >> FOO_EVENT:DFL_GROUP:x=8 >> > I think we need to distinguish between default and hardcoded as part of a > unit mask.
Correct. We should not allow the overriding of umasks or modifiers that need to be set in a certain way to correctly record an event. My first approach for that was simply to make the hard-coded umask/modifiers unavailable for that event. > In your case I suspect x=0 is part of DFL_GROUP, i.e., it is > necessary for DFL_GROUP to measure what its definition says it measures. > In that case, x=8, would be illegal. That's different from a default which > is not part of any specific unit mask definition but it will be used if the > user omits the modifiers (or unit mask). To give a more concrete example, in the processor I'm working on, there is a class of events for which you can set the mode to level or edge counting, depending on what information you want out of it. However, we generally know that most users are going to want, for example, edge counting for these events, so we provide that as a default, but will allow that default to be overridden, or explicitly specified to be the same as the default value, so that, for example: EVENT is equivalent to EVENT:e=1 but can be overridden as EVENT:e=0 Of course the other way to approach this is that if there's any choice, force the user to make a choice rather than assume anything about what he wants. > > Another way of looking at it would be to let the user make mistakes. > Let the user override x with 8. > The existing X86 libpfm4 codebase, refuse to set the value of a modifier > if it is already not zero. But that's specific to X86. It may be that on > Power, a value of 0 may be required for certain unit masks. 0 is just > the neutral value on X86, it could be something else on Power. This is > all in PMU specific code for this reason. > > Perhaps another way, would be to have an additional flag called is_hard_wired which is mutually exclusive with is_dfl. This way you could display the hard-wired umasks and modifier values to the user, but let them know they can't change them. > >> and would that differ from >> >> FOO_EVENT:x=8:DFL_GROUP >> > With the first approach, you would fail DFL_GROUP because it sets a modifier > already set by the user. With the second approach, DFL_GROUP would override > x=8. > >> Or perhaps I am misunderstanding how groups work? Re-reading your proposal, >> it seems that what a group actually does is not encoded into the data >> structure, but rather into the libpfm code. Is that correct? >> > I was thinking of groups more in terms of unit masks. A group > represents a choice of > unit masks to choose from, where at least one must be set. An event may have > more than one group, i.e., at least of mask in each group must be set. > The current > implementation has one group per event (when they have unit masks). I think we > need to extend this notion. For instance, > > EVENTA: > grp1: A, B, C > grp2: D, E, F, G > > That means that you need to set at least one mask in grp1 and one in grp2: > EVENTA:A:D is okay > EVENTA:A:B:F is okay > EVENTA:C is bad > EVENTA:FG is bad > > I think your example adds to this by saying mask A comes from x=0. > I think this info can be hardcoded as part of the unit mask code. This is how > it's done on X86. Of course, you need a way to identify the value that means > 'not set'. If that's not possible, then you need to augment the event > structure > with a field that encodes this. > >> Maybe another way to handle groups is to use "macros" which translate the >> group name string into lower-level umask and modifier strings processed in >> the normal way. As a very simple example: >> >> "MESI" -> "M:E:S:I" >> >> A more complex case might be: >> >> "SOME_GROUP" -> "E:x=0x100:tm=4:k=1:h=1" >> > See my answer above about how to hardcode this. If the hard-coding allows encoding the setting of multiple modifiers/umasks, I think this should be fine. I just don't see how to mix different attributes into a single member of a group, given the structure you provided in the previous post. > >> All defaults could be done via macros. If no macro string within list for a >> specific event is specified, the first one in the list is the default. >> Something like that. Doing this would keep you from having to handle all of >> this in code; the data would drive the translation. These translations >> would have to be event-specific, at worst. > > Please show me a concrete example of the macros. The MESI example was concrete. The other was a random jumble of umasks and modifiers. I was just looking for a way that could express any combination of umasks and modifiers in a clear and simple way, rather than using complex structures. Let me make one that's more complex than MESI and maybe more realistic. Let's say I have an event, call it EVT1, which normally I would want to specify that it's for my CPU thread, but in some cases I want to specify a mask which shows which CPU threads I want it to measure. So I set up a group containing three macros for EVT1: "THIS_CPU_THREAD" -> "ethm=0" // ethm is "enable thread mask" "ALL_CPU_THREADS" -> "ethm=1:thm=0xff" // thm is the thread mask, assuming 8 threads "SOME_CPU_THREADS" -> "ethm=1" // user must specify thm value now (this macro is really not that useful) In addition to this, perhaps I want the event to count level rather than edges, but libpfm has determined edges to be the default. So another group would be for this choice: "EDGES" -> "e=1" "LEVEL" -> "e=0" The default for a particular group is the first one in the group. With these two groups, if I specify just "EVT1", I will effectively get "EVT1:ethm=0:e=1". Since I want level counting, I should specify "EVT1:LEVEL" or equivalently "EVT1:e=0". The definition of a group then, is an array of string pointer pairs: struct attribute_macro { const char *name; const char *translation; }; Groups could be associated with events, per-event if necessary, or however the libpfm4 arch-dependent implementation best deems. And since you have potentially more than one group, you also need an array of groups. So there are a couple of levels indirection needed here: group[i].macro[j]. A group definition would look something like struct attribute_macro *group[] = ... The event string should include one of the members of each group, and if no member of a particular group is specified, you take the first one of the group. One other thing comes to mind is that we might want the capability of having groups for which there is no default, so we still might need a flag for the group which says "0 = has no default, 1 = macro[0] is the default" These translations could be arbitrarily complex, but I think it would make the libpfm code quite easy to read and modify. To handle the hard-wired case, we'd create a group with a single translation in it, which is the hard-wired combination. We could add another flag to the definition of a group that would designate that this macro is hard-wired, and not to change any of the attributes set by this macro. This would add some complexity to the libpfm code, because now it has to check for users attempting to override attributes specified by the hard-wired default. How exactly to do this check, I don't know. Perhaps use a bit vector to designate which attributes have been set by the hard-wired default, and when you encounter an attribute, you check the bit mask to see if this attribute is already hard-wired for this event. To flesh out the group definition with the above in mind, perhaps it could look like this: struct attribute_macro { const char *name; const char *translation; }; struct macro_group { union { uint32_t flags; uint32_t is_hard_wired:1 is_dfl:1; reserved:30; } int ngroups; struct attribute_macro *group[]; } What do you think? - Corey ------------------------------------------------------------------------------ Return on Information: Google Enterprise Search pays you back Get the facts. http://p.sf.net/sfu/google-dev2dev _______________________________________________ perfmon2-devel mailing list perfmon2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/perfmon2-devel