diff --git a/src/urma/tools/urma_perftest/perftest_parameters.c b/src/urma/tools/urma_perftest/perftest_parameters.c index 377d7be7d6f5ee498b41d111aa56ff60094cdc52..2731bcfcf0c9dcea1842c5fe66fda9e82fe577f8 100644 --- a/src/urma/tools/urma_perftest/perftest_parameters.c +++ b/src/urma/tools/urma_perftest/perftest_parameters.c @@ -157,6 +157,8 @@ default: disable.\n"); timeout = 0: return immediately even if no events are ready,\n\ timeout = -1: an infinite timeout,\n\ default: 1000(1s).\n"); + (void)printf(" --hugepage_size Page size for allocated memory. Only support \ +2MB or 1GB currently.\n"); } static perftest_cmd_type_t parse_command(const char *argv1) @@ -318,6 +320,7 @@ static void init_cfg(perftest_config_t *cfg) cfg->use_ctp = false; cfg->wait_jfc_timeout = PERFTEST_DEF_WAIT_JFC_TIME; + cfg->use_huge_page = false; } void print_cfg(const perftest_config_t *cfg) @@ -517,6 +520,7 @@ int perftest_parse_args(int argc, char *argv[], perftest_config_t *cfg) {"ctp", no_argument, NULL, PERFTEST_OPT_CTP}, {"jetty_id", required_argument, NULL, PERFTEST_OPT_JETTY_ID }, {"wait_jfc_timeout", required_argument, NULL, PERFTEST_OPT_WAIT_JFC_TIMEOUT }, + {"hugepage_size", required_argument, NULL, PERFTEST_OPT_PAGE_SIZE }, {NULL, no_argument, NULL, '\0'} }; @@ -799,6 +803,21 @@ int perftest_parse_args(int argc, char *argv[], perftest_config_t *cfg) case PERFTEST_OPT_WAIT_JFC_TIMEOUT: (void)ub_str_to_int(optarg, &cfg->wait_jfc_timeout); break; + case PERFTEST_OPT_PAGE_SIZE: + if (optarg != NULL) { + cfg->use_huge_page = true; + if (strcmp("2MB", optarg) == 0) { + cfg->huge_page = UB_HUGE_PAGE_SIZE_2MB; + } else if (strcmp("1GB", optarg) == 0) { + cfg->huge_page = UB_HUGE_PAGE_SIZE_1GB; + } else if (strcmp("ANY", optarg) == 0) { + cfg->huge_page = UB_HUGE_PAGE_SIZE_ANY; + } else { + (void)fprintf(stderr, "Huge_page only support 2MB, 1GB and ANY.\n"); + return -1; + } + } + break; default: usage(argv[0]); return -1; diff --git a/src/urma/tools/urma_perftest/perftest_parameters.h b/src/urma/tools/urma_perftest/perftest_parameters.h index 019319aa173435d9f9a1cb31eb459dadea7fe797..c85293aa8f2fc07e955fa0fc22ff21e44d48b71c 100644 --- a/src/urma/tools/urma_perftest/perftest_parameters.h +++ b/src/urma/tools/urma_perftest/perftest_parameters.h @@ -14,6 +14,7 @@ #include #include +#include "ub_util.h" #include "urma_types.h" #include "perftest_communication.h" @@ -189,7 +190,8 @@ enum perftest_opts { PERFTEST_OPT_CTP, PERFTEST_OPT_SINGLE_PATH, PERFTEST_OPT_JETTY_ID, - PERFTEST_OPT_WAIT_JFC_TIMEOUT + PERFTEST_OPT_WAIT_JFC_TIMEOUT, + PERFTEST_OPT_PAGE_SIZE }; typedef enum perftest_rate_limiter_units { @@ -288,6 +290,8 @@ typedef struct perftest_config { bool use_ctp; uint32_t jetty_id; int32_t wait_jfc_timeout; + urma_huge_page_size_t huge_page; + bool use_huge_page; } perftest_config_t; typedef struct perftest_value_range { diff --git a/src/urma/tools/urma_perftest/perftest_resources.c b/src/urma/tools/urma_perftest/perftest_resources.c index 7efcd8f31b548b0690279e6e3349b6432c0204d5..05c6fb41efdb4f26a400b61464e174ffaf3f48d9 100644 --- a/src/urma/tools/urma_perftest/perftest_resources.c +++ b/src/urma/tools/urma_perftest/perftest_resources.c @@ -16,7 +16,9 @@ #include #include #include +#include +#include "ub_util.h" #include "urma_api.h" #include "perftest_resources.h" @@ -660,12 +662,20 @@ static inline void free_token_id(perftest_context_t *ctx, const perftest_config_ ctx->token_id = NULL; } -static inline void free_memory(perftest_context_t *ctx, const perftest_config_t *cfg, const int idx) +static void free_memory(perftest_context_t *ctx, const perftest_config_t *cfg, const int idx) { + int ret = 0; uint32_t seg_num = (cfg->seg_pre_jetty == false) ? 1 : cfg->jettys; for (uint32_t j = 0; j < idx; j++) { if (j < seg_num) { - free(ctx->local_buf[j]); + if (cfg->use_huge_page == false) { + free(ctx->local_buf[j]); + } else { + ret = ub_hugefree(ctx->local_buf[j], ctx->buf_len); + if (ret != 0) { + (void)fprintf(stderr, "Failed to free huge page, len: %lu.\n", ctx->buf_len); + } + } } } free(ctx->local_buf); @@ -675,6 +685,8 @@ static inline void free_memory(perftest_context_t *ctx, const perftest_config_t static int register_mem(perftest_context_t *ctx, perftest_config_t *cfg) { uint32_t i = 0, j = 0, k = 0; + const uint64_t page_size_2MB = 2 * 1024 * 1024; + const uint64_t page_size_1GB = 1024 * 1024 * 1024; ctx->local_buf = calloc(1, sizeof(void *) * cfg->jettys); if (ctx->local_buf == NULL) { return -ENOMEM; @@ -683,6 +695,18 @@ static int register_mem(perftest_context_t *ctx, perftest_config_t *cfg) uint32_t seg_num = (cfg->seg_pre_jetty == false) ? 1 : cfg->jettys; ctx->page_size = cfg->page_size; + if (cfg->use_huge_page) { + switch (cfg->huge_page) { + case UB_HUGE_PAGE_SIZE_2MB: + ctx->page_size = page_size_2MB; + break; + case UB_HUGE_PAGE_SIZE_1GB: + ctx->page_size = page_size_1GB; + break; + default: + break; + } + } // holds the size of maximum between cfg->size and page_size, aligned to cache line. uint64_t max_size = MAX(cfg->size, ctx->page_size); @@ -692,14 +716,26 @@ static int register_mem(perftest_context_t *ctx, perftest_config_t *cfg) ((cfg->seg_pre_jetty == true) ? 1 : cfg->jettys); for (i = 0; i < cfg->jettys; i++) { - if (i < seg_num) { - ctx->local_buf[i] = memalign(ctx->page_size, ctx->buf_len); + if (cfg->use_huge_page) { + if (i < seg_num) { + ctx->local_buf[i] = ub_hugemalloc(ctx->buf_len, cfg->huge_page, NULL); + } else { + ctx->local_buf[i] = ctx->local_buf[0]; + } + if (ctx->local_buf[i] == NULL) { + (void)fprintf(stderr, "Failed to alloc local buffer, i: %u.\n", i); + goto free_memory; + } } else { - ctx->local_buf[i] = ctx->local_buf[0]; - } - if (ctx->local_buf[i] == NULL) { - (void)fprintf(stderr, "Failed to memalign local buff: %u!\n", i); - goto free_memory; + if (i < seg_num) { + ctx->local_buf[i] = memalign(ctx->page_size, ctx->buf_len); + } else { + ctx->local_buf[i] = ctx->local_buf[0]; + } + if (ctx->local_buf[i] == NULL) { + (void)fprintf(stderr, "Failed to memalign local buffer, i: %u.\n", i); + goto free_memory; + } } }