stephane eranian wrote:
> On Mon, Dec 7, 2009 at 10:46 PM, Corey Ashford
> <[email protected]> wrote:
>> Hi Stephane,
>>
>> stephane eranian wrote:
>>> On Fri, Dec 4, 2009 at 11:16 PM, Corey Ashford
>>> <[email protected]> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel