monitoring of branch ratios on cores doing busy polling using PMDs as
described below:
-``--core-list {list of cores}``
+``--core-branch-ratio {list of cores}:{branch ratio for listed cores}``
Specify the list of cores to monitor the ratio of branch misses
to branch hits. A tightly-polling PMD thread has a very low
branch ratio, therefore the core frequency scales down to the
minimum allowed value. On receiving packets, the code path changes,
causing the branch ratio to increase. When the ratio goes above
the ratio threshold, the core frequency scales up to the maximum
- allowed value.
+ allowed value. The specified branch-ratio is a floating point number
+ that identifies the threshold at which to scale up or down for the
+ elements of the core-list. If not included the default branch ratio of
+ 0.01 but will need adjustment for different workloads
-``--branch-ratio {ratio}``
- Specify a floating-point number that identifies the threshold at which
- to scale up or down for the given workload. The default branch ratio
- is 0.01 and needs adjustment for different workloads.
+ This parameter can be used multiple times for different sets of cores.
Compiling and Running the Guest Applications
static struct option lgopts[] = {
{ "mac-updating", no_argument, 0, 1},
{ "no-mac-updating", no_argument, 0, 0},
- { "core-list", optional_argument, 0, 'l'},
+ { "core-branch-ratio", optional_argument, 0, 'b'},
{ "port-list", optional_argument, 0, 'p'},
- { "branch-ratio", optional_argument, 0, 'b'},
{NULL, 0, 0, 0}
};
argvopt = argv;
ci = get_core_info();
- while ((opt = getopt_long(argc, argvopt, "l:p:q:T:b:",
+ while ((opt = getopt_long(argc, argvopt, "p:q:T:b:",
lgopts, &option_index)) != EOF) {
switch (opt) {
return -1;
}
break;
- case 'l':
+ case 'b':
+ branch_ratio = BRANCH_RATIO_THRESHOLD;
oob_enable = malloc(ci->core_count * sizeof(uint16_t));
if (oob_enable == NULL) {
printf("Error - Unable to allocate memory\n");
}
cnt = parse_set(optarg, oob_enable, ci->core_count);
if (cnt < 0) {
- printf("Invalid core-list - [%s]\n",
+ printf("Invalid core-list section in "
+ "core-branch-ratio matrix - [%s]\n",
optarg);
free(oob_enable);
break;
}
+ cnt = parse_branch_ratio(optarg, &branch_ratio);
+ if (cnt < 0) {
+ printf("Invalid branch-ratio section in "
+ "core-branch-ratio matrix - [%s]\n",
+ optarg);
+ free(oob_enable);
+ break;
+ }
+ if (branch_ratio <= 0.0 || branch_ratio > 100.0) {
+ printf("invalid branch ratio specified\n");
+ return -1;
+ }
for (i = 0; i < ci->core_count; i++) {
if (oob_enable[i]) {
- printf("***Using core %d\n", i);
+ printf("***Using core %d "
+ "with branch ratio %f\n",
+ i, branch_ratio);
ci->cd[i].oob_enabled = 1;
ci->cd[i].global_enabled_cpus = 1;
+ ci->cd[i].branch_ratio_threshold =
+ branch_ratio;
}
}
free(oob_enable);
break;
- case 'b':
- branch_ratio = 0.0;
- if (strlen(optarg))
- branch_ratio = atof(optarg);
- if (branch_ratio <= 0.0) {
- printf("invalid branch ratio specified\n");
- return -1;
- }
- ci->branch_ratio_threshold = branch_ratio;
- printf("***Setting branch ratio to %f\n",
- branch_ratio);
- break;
/* long options */
case 0:
break;
* down. Each core_details struct has it's own array.
*/
freq_window_idx = ci->cd[core].freq_window_idx;
- if (ratio > ci->branch_ratio_threshold)
+ if (ratio > ci->cd[core].branch_ratio_threshold)
ci->cd[core].freq_directions[freq_window_idx] = 1;
else
ci->cd[core].freq_directions[freq_window_idx] = 0;
min = idx;
else /* avoid continuous '-' */
return -1;
- } else if ((*end == ',') || (*end == '\0')) {
+ } else if ((*end == ',') || (*end == ':') || (*end == '\0')) {
max = idx;
if (min == num)
return -1;
str = end + 1;
- } while (*end != '\0');
+ } while ((*end != '\0') && (*end != ':'));
+
+ return str - input;
+}
+
+int
+parse_branch_ratio(const char *input, float *branch_ratio)
+{
+ const char *str = input;
+ char *end = NULL;
+
+ while (isblank(*str))
+ str++;
+
+ if (*str == '\0')
+ return -1;
+
+ /* Go straight to the ':' separator if present */
+ while ((*str != '\0') && (*str != ':'))
+ str++;
+
+ /* Branch ratio not specified in args so leave it at default setting */
+ if (*str == '\0')
+ return 0;
+
+ /* Confirm ':' separator present */
+ if (*str != ':')
+ return -1;
+
+ str++;
+ errno = 0;
+ *branch_ratio = strtof(str, &end);
+ if (errno || end == NULL)
+ return -1;
+
+ if (*end != '\0')
+ return -1;
+
+ str = end + 1;
return str - input;
}
int
parse_set(const char *, uint16_t [], unsigned int);
+int
+parse_branch_ratio(const char *input, float *branch_ratio);
+
#ifdef __cplusplus
}
#endif
ci = get_core_info();
ci->core_count = get_nprocs_conf();
- ci->branch_ratio_threshold = BRANCH_RATIO_THRESHOLD;
ci->cd = malloc(ci->core_count * sizeof(struct core_details));
memset(ci->cd, 0, ci->core_count * sizeof(struct core_details));
if (!ci->cd) {
}
for (i = 0; i < ci->core_count; i++) {
ci->cd[i].global_enabled_cpus = 1;
+ ci->cd[i].branch_ratio_threshold = BRANCH_RATIO_THRESHOLD;
}
printf("%d cores in system\n", ci->core_count);
return 0;
uint16_t freq_directions[FREQ_WINDOW_SIZE];
uint16_t freq_window_idx;
uint16_t freq_state;
+ float branch_ratio_threshold;
};
struct core_info {
uint16_t core_count;
struct core_details *cd;
- float branch_ratio_threshold;
};
#define BRANCH_RATIO_THRESHOLD 0.1