summaryrefslogtreecommitdiff
path: root/perf/benchmark/bcm_benchmark.c
diff options
context:
space:
mode:
authorliuyu <[email protected]>2024-07-07 22:55:37 -0400
committerliuyu <[email protected]>2024-07-07 22:55:37 -0400
commitee1cbf37fc0c08895ed70723029bfbce5f68c060 (patch)
treec6437570be6a0b9e2fa4797dbcb158eb260766db /perf/benchmark/bcm_benchmark.c
parentd122b40e7633d24ea832175a8339324c9f43beaa (diff)
The first releaseHEADmaindev-utdev
Diffstat (limited to 'perf/benchmark/bcm_benchmark.c')
-rw-r--r--perf/benchmark/bcm_benchmark.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/perf/benchmark/bcm_benchmark.c b/perf/benchmark/bcm_benchmark.c
new file mode 100644
index 0000000..5a7db7a
--- /dev/null
+++ b/perf/benchmark/bcm_benchmark.c
@@ -0,0 +1,153 @@
+/*
+ * @Author: liuyu
+ * @LastEditTime: 2024-07-07 21:19:02
+ * @Email: [email protected]
+ * @Describe: TODO
+ */
+#include "bbq.h"
+#include "bcm_queue.h"
+#include "iniparser.h"
+#include "ut_bbq_func.h"
+#include <pthread.h>
+#include <stdatomic.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+void bcm_report_printf(struct ut_cfg *cfg, struct ut_merge_data *data, struct ut_exit_data **raw_data, uint32_t thread_cnt, enum ut_thread_type ttype) {
+ char name[10] = {0};
+ double latency_ns = 0;
+ double throughput = 0;
+
+ printf("\n---------%s---------\n", ttype == UT_THREAD_PRODUCER ? "生产者" : "消费者");
+ double use_time = ut_clock_time_to_double(&data->use_time);
+ printf("执行时间 : %lf 秒\n", use_time);
+ printf("执行次数 : %lu (burst=%u)\n", data->run_times, cfg->ring.burst_cnt);
+ printf("成功%s : %lu\n", ttype == UT_THREAD_PRODUCER ? "入队" : "出队", data->ok_cnt);
+ printf("数据错误次数 : %lu\n", data->data_error_cnt);
+
+ // 同时有生产者、消费者时才输出
+ if (cfg->ring.producer_cnt > 0 && cfg->ring.consumer_cnt > 0) {
+ throughput = data->ok_cnt / use_time;
+ printf("吞吐 :%.0lf/s (%e/s)\n", throughput, throughput);
+
+ // 多生产者单消费者 或 单生产者多消费才输出
+ if ((cfg->ring.producer_cnt == 1 && cfg->ring.consumer_cnt > 1) ||
+ (cfg->ring.producer_cnt > 1 && cfg->ring.consumer_cnt == 1)) {
+ for (uint32_t i = 0, bbq_head_idx = 1; i < thread_cnt; i++) {
+ if (raw_data[i]->arg->ttype == ttype) {
+ struct ut_metric tmp_time = ut_clock_time_sub(raw_data[i]->metric_end, raw_data[i]->metric_start);
+ throughput = raw_data[i]->ok_cnt / ut_clock_time_to_double(&tmp_time);
+ printf(" %s-%d 吞吐 :%.0lf/s (%e/s)", name, bbq_head_idx, throughput, throughput);
+ bbq_head_idx++;
+ }
+ }
+ }
+
+ if (ttype == UT_THREAD_CONSUMER && cfg->ring.workload == UT_WORKLOAD_COMPLEX) {
+ latency_ns = data->latency_ns * 1.0 / data->ok_cnt;
+ printf("数据延迟 :%.0lf 纳秒 (%e)\n", latency_ns, latency_ns);
+ }
+
+ latency_ns = data->op_ok_latency_ns * 1.0 / data->ok_cnt;
+ printf("操作延迟 :%.0lf 纳秒 (%e)\n", latency_ns, latency_ns);
+ } else {
+ latency_ns = data->op_err_latency_ns * 1.0 / (data->run_times - data->ok_cnt);
+ if (ttype == UT_THREAD_PRODUCER) {
+ printf("满队入队操作延迟 :%.0lf 纳秒 (%e)\n", latency_ns, latency_ns);
+ } else {
+ printf("空队出队操作延迟 :%.0lf 纳秒 (%e)\n", latency_ns, latency_ns);
+ }
+ }
+}
+
+void bcm_report_generate(struct ut_cfg *cfg, struct ut_exit_data **exit_data, uint32_t thread_cnt) {
+ // ut_report report;
+
+ struct ut_merge_s merge = {0};
+ ut_merge_all_data(exit_data, thread_cnt, &merge);
+
+ printf("ring类型: %s\n", ut_ring_type_enum2str(cfg->ring.ring_type));
+ printf("简介: %s\n", cfg->base.introduce);
+ printf("配置: %s\n", cfg->base.name);
+ if (cfg->ring.producer_cnt > 0) {
+ bcm_report_printf(cfg, &merge.producer, exit_data, thread_cnt, UT_THREAD_PRODUCER);
+ }
+
+ if (cfg->ring.consumer_cnt > 0) {
+ bcm_report_printf(cfg, &merge.consumer, exit_data, thread_cnt, UT_THREAD_CONSUMER);
+ }
+
+ if (cfg->ring.producer_cnt > 0 && cfg->ring.consumer_cnt > 0) {
+ printf("生产消费个数验证: %s\n", merge.consumer.ok_cnt == merge.producer.ok_cnt ? "相等" : "不等!!!!!!!!!");
+ }
+}
+
+int main(int argc, char *argv[]) {
+ char *config;
+ char *ring_type;
+ uint32_t burst_cnt = 0;
+
+ if (argc == 4) {
+ config = argv[1];
+ ring_type = argv[2];
+ burst_cnt = strtoul(argv[3], NULL, 0);
+ if (burst_cnt <= 0) {
+ burst_cnt = 1;
+ }
+ } else {
+ config = "/root/code/c/bbq/perf/benchmark/config/compare/case1_simple_spsc.ini";
+ ring_type = "dpdk";
+ burst_cnt = 16;
+ UT_ERR_LOG("use default config, ringt_type:%s burst:%u config:%s argc:%d", ring_type, burst_cnt, config, argc);
+ }
+
+ char thread_name[128] = {0};
+ snprintf(thread_name, sizeof(thread_name), "main:%lu", pthread_self());
+ prctl(PR_SET_NAME, thread_name);
+
+ // 加载配置
+ struct ut_info_s info;
+ if (ut_load_config(config, ring_type, burst_cnt, &info.cfg) != 0) {
+ UT_ERR_LOG("load config error");
+ return -1;
+ }
+
+ // 队列初始化
+ int ret = -1;
+ struct ut_queue q;
+ ret = bcm_queue_init(&info.cfg, &q);
+ if (ret != 0) {
+ UT_ERR_LOG("init failed :%d", ret);
+ return ret;
+ }
+
+ // 创建线程
+ pthread_t *threads = ut_threads_create(&info, &q);
+ if (threads == NULL) {
+ UT_ERR_LOG("pthread_arr is NULL");
+ return ret;
+ }
+
+ // 等待所有线程完成,回收数据
+ uint32_t thread_cnt = info.cfg.ring.producer_cnt + info.cfg.ring.consumer_cnt;
+ struct ut_exit_data **exit_data = (struct ut_exit_data **)ut_malloc(UT_MODULE_BCM, sizeof(struct ut_exit_data **) * (thread_cnt));
+ uint32_t i = 0;
+
+ ut_wait_all_threads_exit(&info, thread_cnt, threads, exit_data);
+
+ // 生成benchmark报告
+ bcm_report_generate(&info.cfg, exit_data, thread_cnt);
+
+ // 回收、释放数据
+ for (i = 0; i < thread_cnt; i++) {
+ ut_exit_data_destory(exit_data[i]);
+ }
+ ut_free(UT_MODULE_BCM, exit_data);
+ ut_threads_destory(&info, threads);
+ ut_queue_destory(&q);
+ ut_memory_counter_print();
+
+ return 0;
+} \ No newline at end of file