在PAPI中添加7个事件到事件集返回-1(PAPI_EINVAL)求助
Let's break down why your PAPI_start_counters call is failing with PAPI_EINVAL and fix it step by step. The issue almost certainly isn't related to PAPI_NUM_TLS—that controls thread-local storage settings, which don't affect event set validity. Here's what to check:
1. Always Validate PAPI Library Initialization
You're calling PAPI_library_init, but you aren't checking if it succeeded. A failed initialization will break every subsequent PAPI call. Add this critical check first:
int retval = PAPI_library_init(PAPI_VER_CURRENT); if (retval != PAPI_VER_CURRENT && retval > 0) { fprintf(stderr, "PAPI library version mismatch!\n"); exit(EXIT_FAILURE); } if (retval < 0) { fprintf(stderr, "PAPI initialization failed: %s\n", PAPI_strerror(retval)); exit(EXIT_FAILURE); }
2. Check if All Events Are Supported on Your CPU
Not all PAPI preset events work across every CPU architecture. Some events in your list (like PAPI_L3_TCM or PAPI_TLB_IM) might not be available on your system. Test each event individually with PAPI_query_event:
int events1[] = { PAPI_L1_TCM, PAPI_L2_TCM, PAPI_L3_TCM, PAPI_MEM_WCY, PAPI_RES_STL, PAPI_TLB_DM, PAPI_TLB_IM }; int num_events = sizeof(events1) / sizeof(events1[0]); for (int j = 0; j < num_events; j++) { if (PAPI_query_event(events1[j]) != PAPI_OK) { fprintf(stderr, "Event %s is NOT supported on your hardware!\n", PAPI_event_code_to_name(events1[j])); } }
If any event fails this check, remove it from your set or replace it with an architecture-equivalent event.
3. Identify Conflicting Event Combinations
Even if all events work individually, some can't be counted simultaneously—they might share hardware counter resources or be mutually exclusive on your CPU. Instead of using PAPI_start_counters directly, build your event set incrementally to spot the conflict:
int EventSet = PAPI_NULL; if (PAPI_create_eventset(&EventSet) != PAPI_OK) { fprintf(stderr, "Failed to create event set: %s\n", PAPI_strerror(retval)); exit(EXIT_FAILURE); } for (int j = 0; j < num_events; j++) { retval = PAPI_add_event(EventSet, events1[j]); if (retval != PAPI_OK) { fprintf(stderr, "Failed to add event %s: %s\n", PAPI_event_code_to_name(events1[j]), PAPI_strerror(retval)); // Clean up and isolate the problematic event/combination PAPI_cleanup_eventset(EventSet); // Optional: Test this event alone to confirm it works if (PAPI_add_event(EventSet, events1[j]) != PAPI_OK) { fprintf(stderr, "%s fails even when added alone\n", PAPI_event_code_to_name(events1[j])); } PAPI_cleanup_eventset(EventSet); } } // If all events were added successfully, start the counters retval = PAPI_start(EventSet); if (retval != PAPI_OK) { fprintf(stderr, "Failed to start counters: %s\n", PAPI_strerror(retval)); }
This will tell you exactly which event (or combination of events) is causing the invalid argument error. Common conflicts happen between TLB events and cache miss events, or events that use the same underlying hardware counter.
4. Check Hardware Counter Limits
Most CPUs have a limited number of physical performance counters (often 4-8). If your 7 events exceed this number, PAPI needs to use multiplexing to time-slice the counters. Enable multiplexing for your event set:
if (PAPI_set_multiplex(EventSet) != PAPI_OK) { fprintf(stderr, "Failed to enable multiplexing: %s\n", PAPI_strerror(retval)); }
You can check how many physical counters your CPU has with:
const PAPI_hw_info_t *hw_info = PAPI_get_hardware_info(); if (hw_info != NULL) { printf("Available physical performance counters: %d\n", hw_info->cntrs); }
Final Notes
PAPI_NUM_TLScontrols how PAPI manages thread-local storage for counters, which isn't related to event set validity—you can stop adjusting that.- Always use
PAPI_strerrorto get human-readable error messages instead of just relying on error codes.
内容的提问来源于stack exchange,提问作者bing zhu

