sysbench中内存带宽测试流程

一、命令说明

关于sysbench中内存带宽的测试,使用命令sysbench --test=memory --time=100 run

在运行内存带宽测试,主要在main中的run_test中

在run_test中,有test→ops.init()

二、追查主要接口memory_init

test→ops.init()主要是调用了memory_init

memory_init中包含了对内存写操作的接口设置,如图所示

三、写事件的继续追查

在命令运行时,会先在run_test中会调用worker_thread

worker_thread中调用thread_run

thread_run中调用test->ops.execute_event

而test->ops.execute_event即为上图中所赋值的event_seq_write

四、确认关键接口

通过找出关键测试函数event_seq_write

找到SIZE_T_STORE

进一步找到ck_pr_store_32

找到CK_PR_STORE_SAFE

使用的是ck_pr_md_store_32这个函数

五、确认宏定义的数据

关于CK_PR_STORE_SAFE

#define CK_PR_STORE_SAFE(DST, VAL, TYPE)            \
    ck_pr_md_store_##TYPE(                  \
        ((void)sizeof(*(DST) = (VAL)), (DST)), \
        (VAL))

1. 宏参数:

  • DST:目标位置的指针。
  • VAL:要存储的值。
  • TYPE:类型标识符,用于选择合适的存储函数。

2. 宏展开:

  • ck_pr_md_store_##TYPE:通过宏拼接操作,生成特定类型的存储函数名。例如,如果 TYPE 是 int,则生成 ck_pr_md_store_int。
  • ((void)sizeof(*(DST) = (VAL)), (DST)):这是一个复合表达式,首先进行类型检查,然后返回 DST。

3. 类型检查:

  • sizeof(*(DST) = (VAL)):这个表达式的作用是检查 DST 指向的类型是否可以赋值为 VAL 的类型。如果类型不匹配,编译器会报错。
  • (void):将 sizeof 的结果转换为 void,以避免编译器警告。
  • (DST):最终返回 DST,作为存储函数的第一个参数。

4. 存储操作:

  • ck_pr_md_store_##TYPE((DST), (VAL)):调用生成的存储函数,将 VAL 存储到 DST

关于ck_pr_md_store_32这个函数是在这里CK_PR_STORE注册的

内联函数定义ck_pr_md_store_*类型函数,通过定义CK_PR_STORE_S为CK_PR_STORE,后面调用CK_PR_STORE_S(32, uint32_t, "str"),初始化ck_pr_md_store_32函数

六、确认主要测试流程

关于内联函数宏定义CK_PR_STORE的说明:

#define CK_PR_STORE(S, M, T, I)                 \
    CK_CC_INLINE static void                \
    ck_pr_md_store_##S(M *target, T v)          \
    {                           \
        __asm__ __volatile__(I " %w1, [%0]"     \
                    :           \
                    : "r" (target),     \
                      "r" (v)       \
                    : "memory");        \
        return;                     \
    }

这个宏定义 CK_PR_STORE 是用来生成一个内联的汇编函数,用于将一个值存储到指定的目标地址。宏定义的参数和内联汇编的使用可能会让人感到困惑,下面是对这个宏的详细解释:

1. 宏定义的参数

  • S: 用于生成函数名的一部分。
  • M: 目标地址的类型。
  • T: 要存储的值的类型。
  • I: 汇编指令。

2. 宏定义展开后的函数

宏定义展开后会生成一个内联的静态函数,函数名为 ck_pr_md_store_##S,其中 ## 是预处理器的连接符,用于将 S 连接到函数名的一部分。

3. 内联汇编解释

内联汇编部分使用了 GCC 的内联汇编语法,具体解释如下:

  • asm volatile(I " %w1, [%0]": 这是内联汇编指令,其中 I 是传入的汇编指令,%w1 和 [%0] 是操作数。
  • : : "r" (target), "r" (v) : "memory": 这是内联汇编的操作数部分。
  • : : "r" (target), "r" (v): 这是输入操作数,"r" 表示使用通用寄存器,target 和 v 分别是目标地址和要存储的值。
  • : "memory": 这是告诉编译器该汇编代码会修改内存。

示例

假设我们要生成一个将整数值存储到目标地址的函数,可以这样使用这个宏:

#define CK_PR_STORE_INT(M, T) CK_PR_STORE(int, M, T, "str")

CK_PR_STORE_INT(int, int)

展开后生成的函数如下:

CK_CC_INLINE static void
ck_pr_md_store_int(int *target, int v)
{
    __asm__ __volatile__("str %w1, [%0]"
                         :
                         : "r" (target),
                           "r" (v)
                         : "memory");
    return;
}

这个函数会将一个整数值 v 存储到目标地址 target。

综上所述SIZE_T_STORE最终的函数为ck_pr_md_store_32(int *, int )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值