220 likes | 386 Views
中期报告: 针对多线程程序的二进制翻译器 中的 code cache 管理策略. 报告人: 张盈 导师: 武成岗 时间: 2009.3. 目录. 研究意义 研究背景 多线程共享 Code Cache 分单元管理策略 本地码的链接和断链 永不替换的本地码 Code Cache 替换算法 更新当前执行指令地址 同步操作 无锁哈希表操作 项目及课程完成情况. 研究意义. 二进制翻译多线程程序 龙芯与 x86 的兼容 用 X86_64 平台提升 X86 32 位二进制程序的性能 多线程程序应用广泛
E N D
中期报告:针对多线程程序的二进制翻译器中的code cache管理策略 报告人: 张盈 导师: 武成岗 时间: 2009.3
目录 • 研究意义 • 研究背景 • 多线程共享Code Cache分单元管理策略 • 本地码的链接和断链 • 永不替换的本地码 • Code Cache替换算法 • 更新当前执行指令地址 • 同步操作 • 无锁哈希表操作 • 项目及课程完成情况
研究意义 • 二进制翻译多线程程序 • 龙芯与x86的兼容 • 用X86_64平台提升X86 32位二进制程序的性能 • 多线程程序应用广泛 • 高效的code cache管理策略 • 许多应用属于大型应用 • 二进制翻译带来代码膨胀 • 大量的IO操作影响程序性能 • 操作系统虚存管理的劣势 • 嵌入式系统的应用 • 研究现状 • Dynamo已实现支持多线程的二进制翻译器,但不支持共享Code Cache的替换 i386可执行码 二进制翻译系统 ? 目标平台
目录 • 研究意义 • 研究背景 • 多线程共享Code Cache分单元管理策略 • 本地码的链接和断链 • 永不替换的本地码 • Code Cache替换算法 • 更新当前执行指令地址 • 同步操作 • 无锁哈希表操作 • 项目及课程完成情况
背景介绍 • Digital Bridge框架
背景介绍 库函数pthread_create • 二进制翻译下的x86多线程程序执行流程 x86的线程栈 库函数clone() 线程函数入口 线程flag 线程参数指针 • 申请DBT的线程栈 • 调用本地系统调用 • clone创建DBT子线程来 • 翻译执行X86子线程 do_clone() 系统调用clone(...) 父线程返回,子线程调用线程函数入口
背景介绍 • 线程独立与线程共享 • 大多数结构都可以选择线程独立或者共享 • 线程独立空间-由寄存器变量env来指向 • 线程独立与线程共享code cache比较 • 线程独立:实现较简单,cache管理带来的竞争相对较小,较好的程序局部性,但是会增大翻译的开销,带来更大代码膨胀。 • 线程共享:翻译开销和代码膨胀都较小,但是竞争和同步的开销较大。 • 选择:根据程序共享代码特性。 • 由于线程独立的cache不适应multi-threaded结构的程序,因此本文实现线程共享的cache。
目录 • 研究意义 • 研究背景 • 多线程共享Code Cache分单元管理策略 • 本地码的链接和断链 • 永不替换的本地码 • Code Cache替换算法 • 更新当前执行指令地址 • 同步操作 • 无锁哈希表操作 • 项目及课程完成情况
本地码的链接和断链 • 本地码链接 • 减小上下文切换开销 • 本地码断链 • 组织线程进入被替换的Unit 本地码链接示意图 6 jmp target_address 5 5 3 bytes of target_address 本地码链接指令序列 本地码断链指令序列
永不替换的本地码 • 线程同步功能的基本块需要放入永不替换的单元中 • 同步功能:系统调用,同步指令 • 空间开销 • 在SPEC2000INT测试例子中约1% Thread 2 needs code cache deadlock Code Cache Thread 1 sleeping 功能示意图
Code Cache替换算法 • 分Unit的FIFO替换策略 • 多线程的Unit替换条件 • 没有线程在被替换Unit中执行 • 1、外部线程不能进入 • 本地码地址在哈希表中失效 • 断开被替换Unit前驱的本地码链接 • 2、内部线程立即离开 • 断开被替换Unit中循环的回边 Unit 1 Unit 2 … Unit N 不替换的Unit 分Unit的FIFO策略
更新当前执行指令地址 • 示意图
更新当前执行指令地址 • 时间开销 • 用例:SPEC2000INT • 2个Unit时平均5% • SPEC中对间接跳转性能敏感的例子随着Unit数增加,性能下降较多 Hiser, Jason D. Williams, Daniel Hu, Wei Davidson, Jack W. Mars, Jason Childers, Bruce R. Evaluating Indirect Branch Handling Mechanisms in Software Dynamic Translation Systems,CGO '07
更新当前执行指令地址 • 时间开销 • 用例:MYSQL • 2个Unit时平均2.5%,4个Unit时平均7%
更新当前执行指令地址 • 空间开销 • 方法1:用公共的检查单元没有空间开销 • 方法2:每个基本块数据结构中增加2~4条指令作为检查单元,相对Code Cache有 25~50%的空间增加
同步操作 • 保证原程序同步语义 • 原程序中信号机制,由本地的信号处理程序来调用x86的信号处理程序 • 原程序中的原子锁 • 识别含有lock前缀和xchg,cmpxchg指令,保证锁的原子性 • DBT中的同步保证正确性 • 为全局共享的变量加锁
同步操作-细粒度的锁 • 目标 • 减少启动时间 • 增加Code Cache替换时的并发度 二进制翻译系统中的锁 锁的相互作用
计算哈希函数: • x86_pc_t tb_phys_hash_func(x86_pc) • { • return x86_pc & (CODE_GEN_PHYS_HASH_SIZE - 1); • } • 查找哈希表: • TranslationBlock* Lookup ( x86_pc){ • h = tb_phys_hash_func(x86_pc); • head_addr = &hashtable[h]; • thread_local_storage->hash_tmp_ptr = *head_addr; • tb = thread_local_storage ->hash_tmp_ptr; • while (true) { • if (!tb) • return NULL; • if (tb->pc == pc) • return tb; • head_addr = &tb->phys_hash_next; • tb = *head_addr; • } • } • 更新哈希表: • void Insert( tb ){ • h = tb_phys_hash_func(x86_pc); • head_addr = &tb_phys_hash[h]; • while (true) { • hash_tmp_ptr = thread_local_storage ->hash_tmp_ptr; • tb->phys_hash_next = thread_local_storage ->hash_tmp_ptr; • if(CAS(head_addr, &thread_local_storage ->hash_tmp_ptr, tb )){ • return; • } • else{ • tmptb = *head_addr; • while(tmptb != hash_tmp_ptr){ • if(tmptb->pc == tb->pc) • return; • tmptb = tmptb->phys_hash_next; • } • } • } • } • 查找并更新哈希表 • TranslationBlock* Lookup_And_Insert ( x86_pc){ • TranslationBlock* tb =Lookup ( x86_pc ); • if (!tb){ • tb = tb_alloc(pc); • Insert( tb ); • } • else • return; • } 无锁哈希表 • 哈希表基本操作 • 查找本地码 • 添加基本块 • 删除基本块 • 先将基本块结点设上无效标志并在一个延迟的时间点统一删除(未实现)
待完成的内容 • 实验 • 测量在发生Code Cache替换时的等待时间 • 测量其余为了提高多线程并发度而做的改进,包括无锁哈希表以及细粒度的锁。 • 进一步研究 • 减少更新当前执行指令地址的时空开销 • 软件Code Cache替换对硬件Cache局部性的影响
目录 • 研究意义 • 研究背景 • 多线程共享Code Cache分单元管理策略 • 本地码的链接和断链 • 永不替换的本地码 • Code Cache替换算法 • 更新当前执行指令地址 • 同步操作 • 无锁哈希表操作 • 项目及课程完成情况
项目及课程完成情况 • 已受理专利 • 2008ICT76(BJ406-08P106420)二进制翻译器中线程共享code cache的替换方法及系统 • 参加项目 • 课程学习