Corey, On Tue, Dec 8, 2009 at 11:49 PM, Corey Ashford <cjash...@linux.vnet.ibm.com> wrote: > > 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 > Yes, that's what I would expect for a default. It's there is the modifier is not specified, but it is skipped if the modifier is specified by the user.
> 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. > That's what happens today with unit masks, but not with modifiers. > 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. > The only reason you would want to expose that is for tools to either detect early on invalid event string or post-mortem print meaningful error messages. Other than that, what's the point of exposing that level of details? >> 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 have been thinking about the grouping issue some more. I think I have a solution to ensure that at least one elment of each group is selected either explicitly or because it has a default. This is similar to coloring. In the table you tag each unit mask, with a group id. In each group at least one unit mask must be set. If it is not and there is no default, then there is an error. At the event level, the table would contain the number of groups. to get back to me example above: { .name = "EVENTA", .ngrp = 2, .umasks = { { .name = "A", .grp = 0, .flags = IS_DFL }, { .name = "B", .grp = 0 }, { .name = "C", .grp = 0 }, { .name = "D", .grp = 1 }, { .name = "E", .grp = 1 }, { .name = "F", .grp = 1 , flags = IS_DFL }, { .name = "G", .grp = 1 }, } } The library would check that the event string contains at least one unit mask in each group. A simply mask would suffice. In this case, the bitmask would have to be equal to 0x3, otherwise there is an error (0x3 = (1 << event.ngrp) -1). Before making that final check, the library would look for a default in each group if one bit is missing from the mask. >>> 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. > Yes, I think there is an issue if you want to report that an attribute, e.g., a unit masks hardcodes a unit mask code + a bunch of modifiers. > 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) > Ok, so here you are talking about a macro to represent a group of preset modifiers. And then, I am assuming you use that in the list of unit masks for an event or as a attribute of a unit mask. It's as if you were defining super-modifiers which gather a set of modifiers + values. We could easily define super-modifiers, internally the library would map that to each individual modifier + value. I think what is more difficult in all of this is how to report this to the user (assuming it could be 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" > That seems less useful because the 'e' modifier is already published. So what's the value of adding yet another layer of indirection. Each modifier has a description that explain what it does. > 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". > It seems to me that we are leaning towards some libpfm call that would describe what each event+attr actually define. You'd like for each event and for each unit mask to figure: - what is the unit mask code - what is the value of EACH modifier for it That is different from what i was proposing which was simply iterating over each attribute individually reporting its code and whether or not it was the default. I believe the former proposal is probably more useful to applications. Yet it is more difficult to create data structures to represent the information because the number of modifiers is highly variable. Let's take an example to illustrate what we would like. Let's assume we have the following event: attrs[]={ 0 { .name = "e", .type = BOOL }, 1 { .name = "i", type = BOOL }, 2 { .name = "eth", .type = INTEGER}, }; { .name = "EVT1", .code = 0xa0, .ngrp = 1, .attrmsk = 0x7, .numasks = 2, .umasks = { { .name = "UM1", .code = 0x1 .flags = IS_DEFAULT, .grp = 0, }, { .name = "UM2", .mods = "e=1:eth=2", .code = 0x1 .grp = 0, }, } } The unit mask UM2 is a variation of UM1, except it has some modifiers hardcoded. Using a string may be a compact way of expressing hardcoded modifiers in the event table itself. The next challenge is how to expose this to the user: maybe as a string. It may be easier for a tool to use strstr() to detect whether or not certain modifiers were specified wrongly. That is also very flexible and extensible. The get_event_attr_info() would return the mods string for each unit mask along with whether or not it is default or not. Calling this function with an index of a attribute that corresponds to a modifier could be useful for some modifiers such as priv level. Note that this scheme would not prevent what you proposed with super-modifiers representing groups of modifiers. Does it cover all the needs you've expressed? > 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