精华内容
下载资源
问答
  • 从奔腾(Penium)系列开始,IntelX86 处理器中增加了一个64位的时间戳寄存器(TSC),每个经过一个时钟周期,该...我们可以计算一下,假设机器的主频是3GMHz,也就是说1秒钟包含3,000,000,000个时钟周期,每个时钟周...

    从奔腾(Penium)系列开始,Intel

    X86 处理器中增加了一个64位的时间戳寄存器(TSC),每个经过一个时钟周期,该寄存器加1;机器重启时,该寄存器将清空。

    现在的处理器其主频都在1G以上,也就是说其时钟周期是纳秒级的(1秒/1000000000=1纳秒)。

    那该寄存器会不会溢出呢?我们可以计算一下,假设机器的主频是3GMHz,

    也就是说1秒钟包含3,000,000,000个时钟周期,每个时钟周期为0.33333纳秒,则64位寄存器溢出所需要的时间为:

    2^64 / 3000000000 ≈

    6148914691 秒 ≈71168天 ≈ 195年

    因此TSC溢出基本是不可能的了。

    RDTSC 是一条机器指令用于读取该时间戳寄存器中的值。

    下面的程序就是通过在C语言调用RDTSC来得到时钟周期:

    #include

    #include

    __int64

    __declspec(naked) read_time_stamp_counter()

    {

    __asm

    cpuid; __asm rdtsc;

    __asm ret;

    }

    int main()

    { float ticks_1, ticks_2;

    unsigned int i,j=0;

    unsigned int loop = 4000000000;

    ticks_1 = (float)read_time_stamp_counter();

    for(i=0;i

    {

    j++;

    j++;

    }

    ticks_2

    = (float)read_time_stamp_counter();

    printf("\ntotal

    ticks is : %f\n", ticks_2-ticks_1);

    printf("\ntotal ticks per loop is : %f\n",

    (ticks_2-ticks_1)/loop);

    printf("\ntotal time is %f seconds\n", (ticks_2 -

    ticks_1)/3300000000);

    return 1;

    }

    说明:

    (1)

    子函数read_time_stamp_counter()并没有明确的指定返回值,为什么程序中仍然可以得到正确的值?原因在于指令RDTSC将时间戳的放在EDX:EAX中,而这与C语言子函数的返回值的存放地址是一致的(参见http://blog.sina.com.cn/s/blog_5d9051c00100jcnj.html)

    (2) 子函数read_time_stamp_counter()的定义中加入__deslspec(naked),

    是避免编译器在编译该函数时添加其他的语句,通过下面的C代码的反汇编可以看到__deslspec(naked)的作用:

    (3) 运行程序的计算机的CPU是3.3GHZ。

    (4) 程序的运行结果如下, 从中可以看出,

    每个循环所耗费的时钟周期是12左右,(注意时钟周期不同于指令周期,指令周期是指执行一条指令所花费的时间,可以用时钟周期表示,一般一个指令周期等于1个或多个时钟周期);根据时钟周期总数和CPU的主频,我们可以计算出整个循环所花费的时间大约是14.83秒。

    展开全文
  • 如何利用rdtsc计算纳秒级的时间

    千次阅读 2015-07-18 09:00:47
    从奔腾系列开始,Intel X86 处理器中增加了一个64位的时间戳寄存器(TSC),每个经过一个时钟周期,该寄存器加1;机器重启时,该寄存器将清空。  现在的处理器其主频都在1G以上,也就是说其时钟周期是纳秒级的...

        从奔腾系列开始,Intel X86 处理器中增加了一个64位的时间戳寄存器(TSC),每个经过一个时钟周期,该寄存器加1;机器重启时,该寄存器将清空。

        现在的处理器其主频都在1G以上,也就是说其时钟周期是纳秒级的(1秒/1000000000=1纳秒)。 

        那该寄存器会不会溢出呢?我们可以计算一下,假设机器的主频是3GMHz, 也就是说1秒钟包含3,000,000,000个时钟周期,每个时钟周期为0.33333纳秒,则64位寄存器溢出所需要的时间为:

             2^64 / 3000000000 ≈ 6148914691 秒 ≈71168天 ≈ 195年

    因此TSC溢出基本是不可能的了。


        RDTSC 是一条机器指令用于读取该时间戳寄存器中的值。

       下面的程序就是通过在C语言调用RDTSC来得到时钟周期:


    #include <windows.h>
    #include <stdio.h>

    __int64 __declspec(naked)read_time_stamp_counter()
    {
         __asm cpuid;  
         __asm rdtsc;
         __asm ret;
    }


    int main()


         float ticks_1, ticks_2;
         unsigned int i,j=0;
         unsigned int loop = 4000000000;

         ticks_1= (float)read_time_stamp_counter();
         for(i=0;i<loop;i++)
         {
             j++;
             j++;
         }

         ticks_2= (float)read_time_stamp_counter();
     
         printf("\ntotal ticks is : %f\n",ticks_2-ticks_1);
         printf("\ntotal ticks per loop is :%f\n", (ticks_2-ticks_1)/loop);
         printf("\ntotal time is %f seconds\n",(ticks_2 - ticks_1)/3300000000);
         return 1;
    }
     

    说明:
    (1)子函数read_time_stamp_counter()并没有明确的指定返回值,为什么程序中仍然可以得到正确的值?原因在于指令RDTSC将时间戳的放在EDX:EAX中,而这与C语言子函数的返回值的存放地址是一致的(参见http://blog.sina.com.cn/s/blog_5d9051c00100jcnj.html
    (2)子函数read_time_stamp_counter()的定义中加入__deslspec(naked),是避免编译器在编译该函数时添加其他的语句,通过下面的C代码的反汇编可以看到__deslspec(naked)的作用:




    (3)运行程序的计算机的CPU是3.3GHZ。


    (4) 程序的运行结果如下,从中可以看出, 每个循环所耗费的时钟周期是12左右,(注意时钟周期不同于指令周期,指令周期是指执行一条指令所花费的时间,可以用时钟周期表示,一般一个指令周期等于1个或多个时钟周期);根据时钟周期总数和CPU的主频,我们可以计算出整个循环所花费的时间大约是14.83秒。


     

    展开全文
  • 本次会学习如何将物理时间的时序,带入到计算机的世界中 第一,clock时钟振荡器 它是某种类型的振子,以一定的固定速率上下波动,并且每一个时钟周期,都作为一个数字整数时间单位。于是,这样就打破了物理时间的...

    本次会学习如何将物理时间的时序,带入到计算机的世界中

    第一,clock时钟振荡器

    它是某种类型的振子,以一定的固定速率上下波动,并且每一个时钟周期,都作为一个数字整数时间单位。于是,这样就打破了物理时间的连续性,他会记录时间1、2、3、4…
    在这里插入图片描述
    图片理解:
    时间1内,非门输入为1,输出为0;
    时间2内,非门输入为0,输出为1;

    计算机上所有的时序逻辑都是一个接一个的整数阶步骤,由于在信号发出时的干扰因素较多,导致一个时间周期内开始发射信号时的曲线不稳定,而在收到信号后可不考虑收到信号的时间。
    因此,一个时间段的输出信号是完全依赖于前一个时间段的输入时间。

    现提出输出时序公式:
    Out[ t ] = function [ in(t-1) ]

    那么,function功能是由什么部件完成的呢?
    两个连续时间之间的过渡点必须有状态,必须记住现在是记住0还是1
    需要用一个寄存器,存储当前时间周期内的信号是1还是0,本次将讨论这个寄存器的结构

    触发器可以记住上次输入,并在下次单元中输出它,弥补空缺;
    在这里插入图片描述
    逻辑:
    在这里插入图片描述

    展开全文
  • 这里有一个很重要的寄存器叫做指令寄存器,也就是指令指针寄存器,其存储的是下一个时钟周期将要执行的指令所在的程序的地址。英文形式为IP(Instruction Pointer)。注意这里的IP不是我们常说的网络IP(网络之间...

    1.首先我们先温习一下计算机系统的结构

     

    1)计算机硬件系统

     

     

     

     

     

    2)计算机软件系统

     

     

     2.计算机的内部工作方式

     

    这里有一个很重要的寄存器叫做指令寄存器,也就是指令指针寄存器,其存储的是下一个时钟周期将要执行的指令所在的程序的地址。英文形式为IP(Instruction Pointer)。注意这里的IP不是我们常说的网络IP(网络之间互连的协议即Internet Protocol)。这里的IP一般是指16位系统的指令指针,如果是32位的则成为EIP,64位的为RIP。

    此外还有一些通用寄存器:

    百度计算机工作原理可以查到其工作原理,计算机在运行时,先从内存中取出第一条指令,通过控制器的译码,按指令的要求,从存储器中取出数据进行指定的运算和逻辑操作等加工,然后再按地址把结果送到内存中去。接下来,再取出第二条指令,在控制器的指挥下完成规定操作。依此进行下去。直至遇到停止指令。程序与数据一样存贮,按程序编排的顺序,一步一步地取出指令,自动地完成指令规定的操作是计算机最基本的工作原理。这一原理最初是由美籍匈牙利数学家冯.诺依曼于1945年提出来的,故称为冯.诺依曼原理。

     

    3.下面我们要从汇编语言的角度分析一下计算机的工作过程。必不可少的会用到堆栈。以32位系统为例,简单介绍一下EIP,EBP,ESP。

    1)EIP寄存器里存储的是CPU下次要执行的指令的地址。

    2)EBP寄存器里存储的是栈的栈底指针,通常叫栈基址。

    3)ESP寄存器里存储的是栈的栈顶指针。并且始终指向栈顶。

    注:以Linux内核使用的AT&T汇编格式为例(右边为目的操作数)。

    下面介绍mov指令以及几种常见的寻址方式(寄存器寻址,立即寻址,直接寻址,间接寻址,变址寻址):

          直接寻址:直接访问一个指定的内存地址的数据。

      间接寻址:将寄存器的值作为一个内存地址来访问内存。

      变址寻址:在间接寻址之时改变寄存器的数值。

    此外还有几个特殊的指令:

            

    注意:ret 相当于pop %eip,eip寄存器不能被直接修改,只能通过特殊的指令间接修改。

    下面是一段C语言代码:

     1 int g(int x)
     2 {
     3   return x + 3; 
     4 }
     5 int f(int x)
     6 {
     7   return g(x)+2; 
     8 }
     9 int main(void)
    10 {
    11   return f(8) + 1;
    12 }

    将其命名为test.c文件

    在linux环境(32位)下输入:

    gcc -S -o test.s test.c -m32

    将会生成test.s文件。打开test.s文件,删除以“.”开头的行,剩余的就是以上C文件对应的汇编代码。(.起始的行是在链接时才用到)    如图:

    注意:

      1.第4行和第12行表示的是基址寄存器的内容加上8后所对应的地址的值存储到eax寄存器,与main函数中的f(8)中的数字8没有任何关系,将8改为0后第4行和第12行仍不变,真正的数字8在第22行。

          2.一般认为的堆栈结构是从上往下地址依次递减的,即push时需要将esp减4(32位,即4个8字节),pop时需要将esp加4(32位)。

    下面进行分析(结合示意图):

     1 g:
     2   pushl %ebp ;         12. 把ebp(4)放入位置七, esp指向下一个标号(7)
     3   movl %esp, %ebp ;    13. ebp指向esp的位置(标号7)
     4   movl 8(%ebp), %eax ; 14. ebp + 8指向标号5(位置五), eax = 8
     5   addl $3, %eax ;      15. eax = eax + 3 = 8 + 3 = 11
     6   popl %ebp ;          16. ebp = 4, esp指向上一个标号(6)
     7   ret ;                17. eip = 15, esp指向上一个编号(5)
     8 f:
     9   pushl %ebp ;         6. ebp(1)放入位置四, esp指向下一个标号(4)
    10   movl %esp, %ebp ;    7. ebp指向esp的位置(标号4)
    11   subl $4, %esp ;      8. esp指向下一个标号(5)
    12   movl 8(%ebp), %eax ; 9. ebp + 8指向标号2(位置二), eax = 8
    13   movl %eax, (%esp) ;  10. 把8放入位置五
    14   call g ;             11. 把eip(15)放入位置六, esp指向下一个标号(6)
    15   addl $2, %eax ;      18. eax = 11 + 2 = 13
    16   leave ;              19. esp指向ebp的位置(标号4); 然后 popl %ebp ,即ebp = 1, esp = 3(esp = esp - 1)
    17   ret ;                20.eip=24, esp上移一个位置(标号2)
    18 main:
    19   pushl %ebp ;         1. 把ebp(0)放入堆栈,位于位置一,同时esp下移指向标号1
    20   movl %esp, %ebp ;    2. 将ebp指向esp的位置(标号1)
    21   subl $4, %esp ;      3. esp减4,指向下一个标号(2)
    22   movl $8, (%esp) ;    4. 把8放入位置二
    23   call f ;             5. 把eip(24)放入位置三, 同时esp指向下一个标号(3)
    24   addl $1, %eax ;      21. eax = 13 + 1 = 14
    25   leave ;              22. esp指向ebp的位置(标号1);然后popl %ebp,即 ebp = 0, esp = 0(esp = esp - 1)
    26   ret ;                23. 回到main函数之前的堆栈

    
    

    注意:

          1.程序是从main函数出执行的。

          2.初始时ebp和esp都指向标号0(就是某内存地址).

          3.分析时要对ebp、esp和eip的功能要了解,对其值要分析准确。

    附:示意图

     

     总结:

      eip,ebp和esp寄存器起到了指示作用,而在内存中可以存储数据也可以存储地址,这在寻址的时候会进行区分。

          函数调用堆栈是高级语言得以运行的基础。

          计算机在执行程序时先将要执行的相关程序和数据放入内存储器中,在执行程序时CPU根据当前程序指针寄存器的内容取出指令,分析并执行指令,然后再取出下一条指令分析并执行,如此循环下去直到程序结束指令时才停止执行。其工作过程就是不断地取指令和执行指令的过程,最后将计算的结果放入指令指定的存储器地址中。

     

    个人感悟:

      计算机很复杂,复杂到我们不能想象;计算机又很简单,简单的只有0和1。想要让计算机更好的为自己工作,就要学习从机器的角度分析。不要因为走的太远而忘记了当初为什么要出发。

     

    PS:由于时间紧促以及个人能力的不足,不能保证没有错误,欢迎任何人批评指正!      

    参考:

     《Linux内核分析》MOOC课程地址:http://mooc.study.163.com/course/USTC-1000029000 

      计算机系统的组成 http://it.dywz.cn/show.aspx?id=339&cid=17

      类似分析 http://www.cnblogs.com/clevercong/p/4321901.html

    转载于:https://www.cnblogs.com/loto-lt/p/4344711.html

    展开全文
  • 解:计算机硬件主要通过不同的时间段来区分指令和数据,即:取指周期(或取指微程序)取出的既为指令,执行周期(或相应微程序)取出的既为数据。 另外也可通过地址来源区分,从PC指出的存储单元取出的是指令,由...
  • 其实这门课在课表中叫做“计算机组织与结构”,不过教材是《计算机组成原理》。...解释周期窃取,并说明为什么DMA方式不能取代程序中断方式 什么是寻址方式,画图解释寄存器间接寻址 根据屏蔽字画出CP
  • 3.5.5 MIPS32处理器设计 指令时间特性分析 */11 CPU设计的主要任务 拟定指令集 数据通路设计 控制器设计 RISC32单/多周期处理器指令周期如何确定时效特性如何? */11 假设各部件的硬件延时10-12秒皮秒 存储器的读写...
  • 1.运算器采用单组内总线、分立寄存器结构和单组内总线、集成寄存器结构时,其输入端设置的部件名称是什么? 2.简述同步控制方式和异步控制方式的定义、特点、优缺点和应用场合,并说明两者最核心的区别是什么? 3....
  • CPU如何选择各模块条? 3. (11分)图B6.1是某SRAM的写入时序,其中R / W 是读 、写命令控制线,当R / W 线为低电平时,存贮器按给定地址把数据线上的数据写入存贮器。请指出图中时序的错误,并画出正确的写入时序。...
  • 如何配置高通平台i2c 时序

    千次阅读 2017-04-14 16:02:19
    Setting I2Cclock dividers I2C规范对I2C时钟脉冲的高电平和低电平周期设置了限制。 为了满足这些限制,可以对QUP寄存器I2C_CLK_CTL...如果hs_div不为0,如何计算fs_div和hs_div的默认值: I2C_FS_CLK =I2C_CLK
  • 前言上一篇文章通过人计算的场景讲解了CPU的整体结构,以及CPU的内存访问和程序执行原理。本文将从人执行任务的场景,讲解CPU读取到指令后的执行过程及内部结构组成,并从中总结出通用的架构原理。CPU如何实现程序...
  • (三)cpu内部如何处理代码的执行

    千次阅读 2019-07-07 12:02:09
    pc寄存器中存储的地址,需要地址译码器来寻址,在偌大的内存中找到对应地址存储的指令后,存入指令寄存器,再通过指令译码器把指令翻译成各个线路的控制信号给到运算器(运算器ALU是没有状态的,只能根据输入计算...
  • JVM内存区域如何划分

    2019-11-22 10:55:31
    PS:(1)非线程共享区域的生命周期与所属线程相同,而线程共享区域与JAVA程序运行生命周期相同,GC只发生在线程共享的区域。 (2)程序计数器无内存溢出异常,其他四个区域会抛出OutofMemoryError异常。 1)程序...
  • 文章目录思维导图:一、CPU的结构1.CPU的功能2.CPU的结构框图3.CPU的寄存器4.控制单元和中断系统5.ALU二、指令周期1.指令周期的基本概念2.指令周期的数据流三、指令流水1.如何提高机器速度2.系统的并行性3.指令流水...
  • 利用TSCL和TSCH来计算时钟周期,这两天看了一下如何他们 DSP开发,测量某个函数或某段代码的cycles消耗是经常要做的 事情,常用的profiling和clock()一般在simulation下使用,真正到了板子上做emulation时,因为要...
  • 这就会造成我们要使用更多的LUT和寄存器,延迟甚至可能超过时钟周期和需要更多的周期计算结果。这往往不是我们需要的结果。因此下面我将介绍如何利用Vivado HLS处理许多位准确或任意精度数据类型,以及允许使用...
  • SysTick定时器

    2014-04-08 17:07:00
    SysTick是一个24位的倒计数定时器,当计到0时,将从...关于Systick定时器的定时间隔10ms在程序中如何计算得到? 利用systick定时器为递减计数器,设定初值并使能它后,它会每个1系统时钟周期计数器减计数到0时,Sy...
  • 个人读书笔记,由于是计算机出身,所以可能理解有误。欢迎指正、讨论。... 基站如何找到手机:手机位置变化时,周期性主动上报位置/存在位置寄存器如何识别手机用户身份:IMSI/ESN + 密码 如何不被...
  • PCI.EXPRESS系统体系结构标准教材.pdf

    热门讨论 2013-02-17 16:21:16
    21.8.3 pci特殊周期事务 第22章 pci兼容配置寄存器 22.1 头类型0(header type 0) 22.1.1 概述 22.1.2 兼容pci的头类型o寄存器 22.1.3 与pci不兼容的头类型o寄存器 22.1.4 用于识别设备驱动程序的寄存器 22.1.5 头...
  • 我的计算机模型是这样的:CPU执行指令,内存犹如一个巨大的字节数组,存储着指令和数据,硬盘保存着各种程序与程序用到的数据。...如果程序员理解了寄存器和内存是如何合作完成任务的,也就明白了...
  • 作为一名程序员,你需要理解计算机存储系统的层次结构,他对应用程序的性能有着巨大的影响,如果程序所需要的数据存储在cpu的寄存器中,那么指令在执行期间,就可以花费零个周期来进行访问,而在Cache中则需要1~30个...
  • 这就会造成我们要使用更多的LUT和寄存器,延迟甚至可能超过时钟周期和需要更多的周期计算结果。这往往不是我们需要的结果。因此下面我将介绍如何利用Vivado HLS处理许多位准确或任意精度数据类型,以及允许使用任
  • HLS中遇到的问题

    2020-03-16 20:52:01
    在HLS优化卷积运算时,乘累加运算是核心计算...可以发现,mul、add、add三个运算在一个时钟周期内完成,从而造成该关键路径超出8ns,那么如何插入寄存器呢?经过几天的探索,终于找到解决方法: 首先定义上述函数,...
  • 6 单周期处理器 6.4 访存指令的控制信号 对于MIPS这样的指令系统来说,其运算指令是不能直接访问存储器的,因此,我们还需要设计单独的访存指令,用来完成寄存器和存储器之间的数据传输。在这一节,我们就来看一看...
  • 12.8086基本总线周期如何组成的?各状态中完成什么基本操作? 答:基本总线周期由4个时钟(CLK)周期组成,按时间顺序定义为T1、T2、T3、T4。在T1期间8086发出访问目的地的地址信号和地址锁存选通信号ALE;T2期间...
  • 单片机期末考试题目及答案详解

    热门讨论 2009-06-23 10:30:30
    当前指令是MUL指令,且正处于取指令机器周期 D.当前正在进行1优先级中断处理 下列功能中不是由I/O接口实现的是 A.数据缓冲和锁存 B.数据暂存 C.速度协调 D.数据转换 18.为给扫描法工作的键盘提供接口电路,...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    用C语言来编写目标系统软件,会大大缩短开发周期,且明显地增加软件的可读性,便于改进和扩充,从而研制出规模更大、性能更完备的系统。 综上所述,用C语言进行单片机程序设计是单片机开发与应用的必然趋势。所以...
  • cpu模型机课程设计.zip

    2010-12-07 13:59:04
    事实上,微程序设计的关键在于纵向设计,即如何确定下一条微指令的地址。通常的做法是先确定微程序分支处的微地址,因为微程序分支处需要进行判别测试。这些微地址确定以后,就可以在一个“微地址表”中把相应的微...
  • 周期管理PLM、面向服务体系架构SOA、商业智能BⅠ、项日管理PM、营销管理、流程管 理 Work Flow、财务管理…..等几乎所有你能想到的应用 3:嵌入式设备及消费类电子产品 包括无线手持设备、智能卡、通信终端、医疗设备...

空空如也

空空如也

1 2
收藏数 38
精华内容 15
关键字:

周期寄存器如何计算