一、命令说明
关于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 )