Hi Stephane, This looks very interesting. A couple of comments/questions below:
stephane eranian wrote: > Corey, >... > I think this is getting quite complicated. > > Let's go back to the problem we were trying to solve. > > The idea is to have an API for tools to discover what are the > default settings for each possible event. Today, some attributes > may be omitted by users in which case the library may pick > some default or simply fail,e.g., unit masks. > > It seems we would like to relax some of the constraints a little > bit. For instance, we would like the library to pick a default > unit mask for some events. I seem to recall Oprofile does that. > > For other attributes such as modifiers (edge, invert, anythread,) > or priv level, we would like the library to pick some defaults as > well. Note that it already does that, all modifiers are 0, unless > hardcoded by the events or unit masks. > > In either case, we need an API to query the defaults, such that > a tool could at least print the full event name string when it prints > the final count. That way, the user would know what was actually > measured. For instance, if I pass UOPS_ISSUED, it is interesting > to know that UOPS_ISSUED:ANY was actually measured. > > There could be multiple default unit masks per event. For instance, > On Intel X86, certain events have unit masks "groups": > > { .name = "L2_LD", > .code = 0x29, > .flags = INTEL_X86_CSPEC|INTEL_X86_MESI, > .cntmsk = 0x3, > .modmsk = INTEL_V2_ATTRS, > .desc = "L2 cache reads", > .umasks = { > INTEL_CORE_MESI_UMASKS, > INTEL_CORE_SPECIFICITY_UMASKS, > INTEL_CORE_HW_PREFETCH_UMASKS > }, > > Where: > #define INTEL_CORE_SPECIFICITY_UMASKS \ > { .uname = "SELF",\ 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\ > } > > #define INTEL_CORE_HW_PREFETCH_UMASKS \ > { .uname = "ANY",\ > .udesc = "All inclusive",\ > .ucode = 0x30\ > },\ > { .uname = "PREFETCH",\ > .udesc = "Hardware prefetch only",\ > .ucode = 0x10\ > } > > 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 would assume it would be, and we'd have to come up with some way of detecting these sorts of errors. If it would be legal to specify one group and then alter it with an individual attribute, would the semantics differ from specifying them in the opposite order? L2_LD:M=0:MESI In this case I'm saying, I want M=0 but MESI otherwise... Assuming this mixing groups and individual attributes is just not allowed, would the following be an error? L2_LD:M=0 ... where you only specify one of the individual attributes and not the others... do the others default to something? They have is_dfl set to zero, but can they still have default values? Or do you start with the default group, and then allow modification of individual attributes (i.e. L2_LD:M=0 would be sort of an implicit L2_LD:MESI:M=0) Also, there definitely needs to be error checking against specifying two groups: L2_LD:ANY:CORE_BOTH:CORE_SELF > > Now how do we go about implementing this? > I have avoided passing complex data structures to libpfm thus far. > The main reason is extensibility and simplicity. The downside > is you have lots of simple calls. We could continue down that > path and add a call just to return the default setting information. > Alternatively, we could go with what I proposed in an earlier > message, basically two calls, one for events, one for attributes > which cover all existing functionalities + the default settings. > > If we go with a dedicated call, then we either have to pass > a struct and a pointer to a boolean (is_default) and a void * > to get the value out. > > I have been toying with the structure approach using the following: > typedef struct { > const char *name; > const char *desc; > pfm_pmu_t pmu; > int idx; > int nattrs; > int size; > uint64_t code; > uint64_t reserved[9]; > } pfm_event_info_t; > > typedef struct { > const char *name; > const char *desc; > pfm_attr_t type; > struct { > int is_dfl:1; /* is default */ > int reserved:31; > }; > int idx; > int size; > uint64_t code; > union { > uint64_t dfl_val64; > const char *dfl_str; > int dfl_bool; > int dfl_int; > }; > uint64_t reserved1[6]; > } pfm_event_attr_info_t; > > int pfm_get_event_info(int idx, pfm_event_info_t *info, size_t sz); > int pfm_get_event_attr_info(int idx, int attr_idx, > pfm_event_attr_info_t *info, size_t sz); > > Advantage is that this is clearly more compact, a couple of calls and you get > everything you need. The more I think about it, the more I think this could be > a workable solution. The type of values is already well covered. There are > reserved field for future extensions. The size parameter is to enable > extensions > the way they do it with perf_events. > > What do you think? If we can resolve the rules for combining default groups with individual attributes, I think this is a good solution, and would provide a tool with lots of useful information to display and options to offer to the user. One downside is that it might be somewhat difficult to describe in the documentation. -- Regards, - Corey Corey Ashford Software Engineer IBM Linux Technology Center, Linux Toolchain Beaverton, OR 503-578-3507 cjash...@us.ibm.com ------------------------------------------------------------------------------ Join us December 9, 2009 for the Red Hat Virtual Experience, a free event focused on virtualization and cloud computing. Attend in-depth sessions from your desk. Your couch. Anywhere. http://p.sf.net/sfu/redhat-sfdev2dev _______________________________________________ perfmon2-devel mailing list perfmon2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/perfmon2-devel