首页 > 其他分享 >测量读写msr寄存器的耗时

测量读写msr寄存器的耗时

时间:2024-09-14 18:12:53浏览次数:8  
标签:__ %% 读写 msr high low 寄存器 ebx

msr寄存器的读写有两个指令rdmsr和wrmsr。他们可以用来读写一些系统相关的寄存器。格式是:

首先向ecx写入msr寄存器的地址,这要查一下手册。对于rdmsr,会将读到的信息,一个64bit数据,高32bit放到edx,低32存访到eax。对于wrmsr,除了向ecx写入msr寄存器的地址,还要向edx和eax写入要写入的值。

读写msr需要在kernel态进行,因此,我们用一个kernel module来实现。下面是一个例子:

#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/slab.h>
 
MODULE_LICENSE("GPL");
 
static inline void mywrmsr(void) {
    unsigned int flag = 0x1d9;
    unsigned int high = 0x0, low = 0;
    unsigned int loop = 100000;
    __asm__ __volatile__ (
        "mov %2, %%ecx\n\t"
        "mov %3, %%ebx\n\t"
        "rdmsr\n\t"
        "1:\n\t"
        "wrmsr\n\t"
        "dec %%ebx\n\t"
        "jnz 1b\n\t"
        : "=r"(high), "=r"(low)
        : "r"(flag), "r"(loop)
        : "%edx", "%eax","%ecx", "%ebx", "memory"
    );
}
 
static inline void myrdmsr(void) {
        unsigned int flag = 0x1d9;
        unsigned int high = 0, low = 0, loop = 100000;
        __asm__ __volatile__(
        "movl %2, %%ecx\n\t"
        "mov %3, %%ebx\n\t"
        "1:\n\t"
        "rdmsr\n\t"
        "dec %%ebx\n\t"
        "mov %%edx, %0\n\t"
        "mov %%eax, %1\n\t"
        "jnz 1b\n\t"
        : "=r"(high), "=r"(low)
        : "r"(flag), "r"(loop)
        : "%eax", "%edx", "%ecx", "%ebx", "memory"
        );
}
 
static inline uint64_t myrdtsc(void) {
    uint32_t low, high;
    __asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high));
    return ((uint64_t)high << 32) | low;
}
 
static int mymsr_init(void)
{
    uint64_t start, end, diff, start_ns, end_ns, diff_ns;
 
    start_ns = ktime_get_raw_ns();
    start = myrdtsc();
 
    mywrmsr();
 
    end = myrdtsc();
    end_ns = ktime_get_raw_ns();
    diff = end - start;
    diff_ns = end_ns - start_ns;
    pr_info("%llu cycles, %llu ns elpased\n", diff, diff_ns);
    return 0;
}
static void mymsr_exit(void)
{
        pr_info("Goodbye mymsr\n");
}
 
module_init(mymsr_init);
module_exit(mymsr_exit);

这个例子在inline 汇编中执行读写msr的循环,从而测量出耗时。

标签:__,%%,读写,msr,high,low,寄存器,ebx
From: https://www.cnblogs.com/banshanjushi/p/18414508

相关文章

  • 二进制读写文件
    提示:文章文章目录前言一、背景二、2.12.2总结前言前期疑问:本文目标:一、背景这个文章主要是针对二进制文件的读写大概会分为c语言对二进制文件读写和c++对二进制文件的读写查找资料看到这篇文章:二进制文件的读写操作,文章是分别对整型变量、数组、字符串进行......
  • Python存储与读写二进制文件
    本文介绍了一种在Python中将Numpy数组转存为一个紧凑的二进制格式的文件,及其使用内存映射的形式进行读取的方案。一个二进制的数据流,不仅可以更加方便页形式的内存映射,相比于传统的Numpy单精度浮点数数组还有一个可哈希的特性。总体来说是一个对于高性能计算十分友好的存......
  • 鼓励读写结合
    在语文学科的教学中,教师要以培养学生的语文核心素养为切入点,以古诗词为载体设计写作环节,强化学生的古诗词阅读体验,引导学生将阅读体验写下来,提高学生写作的主动性和积极性,开发学生思维。以《枫桥夜泊》这首古诗为例,教师可组织开展“古诗新写”的教学活动,引导学生在阅读《枫桥夜泊......
  • lesson04-设计初始化bss段、读写寄存器值的汇编函数
    在内核启动时需要将bss段的所有数据清0,这里就需要memzero函数。.globalmemzero;全局可见memzero:strxzr,[x0],#8subsx1,x1,#8b.gtmemzeroret内核启动时需要经常读写soc内部寄存器的值,这里就需要用到对应的函数put32和get32。.globalput32......
  • stm32 SPI通信外设(硬件SPI读写W25Q64)
    理论1.SPI外设简介STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担可配置8位/16位数据帧、高位先行/低位先行时钟频率:fPCLK/(2,4,8,16,32,64,128,256)支持多主机模型、主或从操作可精简为半双工/单工通信支持DMA兼......
  • stm32之硬件SPI读写W25Q64存储器应用案例
    系列文章目录1.stm32之SPI通信协议2.stm32之软件SPI读写W25Q64存储器应用案例3.stm32之SPI通信外设文章目录系列文章目录前言一、电路接线图二、应用案例代码三、应用案例代码分析3.1基本思路3.2相关库函数介绍3.3MySPI模块3.3.1模块初始化3.3.2SPI基本时序......
  • 单片机寄存器相关知识及应用(51单片机)
    在前面的STM32中我并没有直接对寄存器进行操作,而是通过固件库直接引用进行各个外设的配置和应用,现在,我开始进行寄存器的学习(51单片机)。我们先简单看一下80C51/52的微控制头文件 <REG52.h>一、字节寄存器定义定义了一系列的特殊功能寄存器,如P0、P1、P2、P3、PSW、ACC、B、......
  • stm32 SPI通信协议&W25Q64(软件SPI读写W25Q64)
    理论SPI1.SPI通信SPI(SerialPeripheralInterface)是由Motorola公司开发的一种通用数据总线四根通信线:SCK(SerialClock)、MOSI(MasterOutputSlaveInput)、MISO(MasterInputSlaveOutput)、SS(SlaveSelect)同步,全双工支持总线挂载多设备(一主多从)SCK:时钟线MOSI:主机输出,从......
  • VisualStudio 2022 找不到内存 反汇编 寄存器调试工具
    本文将告诉大家如何解决在VisualStudio2022的调试-窗口里面找不到内存、反汇编、寄存器这三个调试工具的问题找不到的原因是没有启用地址级调试只需要在“工具”(或“调试”)>“选项”>“调试”中选择“启用地址级调试”然后进行调试即可看到开启之后,即可在调试-窗口......
  • MySQL——主从复制、读写分离
    目录前言一、MySQL主从复制的概述1、MySQL主从复制的概念2、Mysql主从复制功能和使用场景2.1、Mysql主从复制功能2.2、Mysql主从复制使用场景3、MySQL支持的复制类型3.1、基于语句的复制3.2、基于行的复制3.3、混合复制4、主从复制的工作过程5、MySQL三种同步方式......