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

Reply via email to