精华内容
下载资源
问答
  • 给出一个基于Windows操作系统的计算机网络同步时钟实现方案,该方案可以有效提高计算机时钟同步精度,在LAN中时钟同步精度达250 μs。同时采用了校正时钟频率误差算法,校正后的时钟长期计时误差能达到10天少于1 s。
  • 要想真正有效地测试、优化程序性能——特别是为Windows服务器开发的多线程程序,操作系统提供的标准时钟是不够的,必须使用解析度更高的时钟。本文介绍了如何访问处理器的十亿分之一秒级别的时钟,极大地提高代码...

    要想真正有效地测试、优化程序性能——特别是为Windows服务器开发的多线程程序,操作系统提供的标准时钟是不够的,必须使用解析度更高的时钟。本文介绍了如何访问处理器的十亿分之一秒级别的时钟,极大地提高代码性能测试的速度和精度。

    一、获取计时数据

    和其他Windows服务器一样,在Windows 2003 Server上最能发挥性能优势的是多线程程序。Windows 2003 Server支持各种多处理器系统,同时也能在单处理器的P4系统上运行。对于单处理器P4系统,Windows 2003 Server将发挥出Intel超线程技术提供的各种硬件线程执行引擎的优势。

    开发服务器应用的人都知道,之所以要开发并行程序,真正的原因只有一个——性能。然而,众所周知,性能改善是一个比较模糊的目标,因为多线程代码的性能通常只能靠经验估计。在单线程程序中,性能改进程度一般可以精确地预知,例如减少了多少指令和延迟较高的操作,但多线程代码不同,Windows平台中线程调度是不确定的,也就是说,在Windows中应用程序可以要求调度程序运行线程,但调度程序何时(是否)运行线程则远远超出了应用程序代码的控制范围。

    在测试性能时,开发者很快会遇到一个问题,这就是Windows内建的标准时钟实在不够精确,其可靠测量事件时间的解析度很难高于一秒,这样,要确定一个代码片段是否真正得到优化就很困难了。如果一定要用Windows的标准时钟进行测试,必须利用循环让代码运行几百万次,才能获得有效的时间数据。绝大多数情况下,使用这类循环意味着修改应用程序。

    其实,还有更好的办法,这就是Win32高解析度时钟,涉及的函数有两个:QueryPerformanceCount(),QueryPerformanceFrequency()。在Intel系统中,从P II开始,这些函数依赖于Pentium芯片内建的一个计数器。当一个Intel系统启动时,一个64位的寄存器跟踪着消逝的时钟周期,这个计数器提供了解析度极高的计时设备。

    整个64位寄存器都要用到。32 bit的整数大约能计数20亿,对于当前每秒运行20-30亿个周期的处理器,32 bit的计数器会在一秒或更少的时间内溢出,64 bit的计数器则能容纳这些秒数的20亿倍,按20亿秒计算就是约63年——可以相信,这已经远远超出测量任何程序的要求了。

    要对一个事件进行计时,只需获得事件开始之前、结束之后的时钟计数。下面的代码不依赖于Win32(即,从C/C++直接访问),稍后我们再看看操作系统提供的函数。我们首先定义一个数据结构,然后再来看填写该结构的代码:

    typedef  struct _BinInt32
    {
    __int32 i32[2];
    } BigInt32;
    
    typedef  struct _BigInt64
    {
        __int64 i64;
    } BigInt64;
    
    typedef union _bigInt
    {
        BigInt32 int32val;
        BigInt64 int64val;
    } BigInt;

    下面的代码从操作系统获得时钟计数器的高位和低位,分别填写__int64数据的两个32 bit部分:

    BigInt start_ticks, end_ticks;
    _asm
    {
        RDTSC
        mov start_ticks.int32val.i32[0], eax
        mov start_ticks.int32val.i32[4], edx
    }

    这段代码能够在Visual Studio .NET 2003中顺利运行,在以前的C/C++编译器中也应该没有问题。RDTSC(ReaD Time Stamp Counter)是一个汇编指令,它的功能是把时间戳计数器的内容装入EAX和EDX寄存器。执行上述代码后,start_ticks就包含了完整的时钟计数。再次调用上面的代码,把start_ticks替换成end_ticks,再从end_ticks减去start_ticks,就得到了两次调用期间流逝的时钟周期。

    要输出这个_int64值,可以使用下面的printf()掩码:

    printf ( "Function used %I64Ld ticks/n", end_ticks.int64val.i64 -
     start_ticks.int64val.i64 );

    Win32函数QueryPerformanceCounter()的功能也大致相似,它唯一的参数是一个指向计数器变量的长指针。如果函数调用失败,它返回0(实际上是FALSE)。然而,上面提供的代码突破了Windows调用的黑箱,即使在非 Windows的Intel系统上,也能发挥同样的功能。

    二、使用计时数据

    如果要把时钟计数转换成时间,只要把时钟计数除以CPU的时钟频率就可以了。不过,芯片上标准的GHz数据往往与实际运行的速度不同。如果要测试芯片的实际速度,除了Win32调用QueryPerformanceFrequency(),还有几种非常好的工具软件。这里要推荐两种工具,首先是Intel自己的Processor Frequency ID Utility,可以从http://support.intel.com/support/

    processors/tools/FrequencyID/FreqID.htm免费下载,它还能提供有关处理器的许多其他信息。另一个工具提供的信息更多,它就是wCPUID,可以从http://www.h-oda.com/免费下载。

    这两种工具都能够测出精确的时钟速度,用前面获得的时钟计数除以速度,就可以得到高精度的时间计数。QueryPerformanceFrequency()函数也只有一个长指针参数,出现错误时返回0或FALSE。

    在如此高的时钟解析度下,许多平常看不到的现象会显现出来。最令人莫名其妙的是,多次测试同一段代码,结果会出现很大的波动。

    大范围波动的主要原因在于读取操作,特别是第一、二两次读取与从缓冲区读取的差异。当代码第一次执行时,一般需要把它装入到缓冲区,代码所操作的数据也一样。用时钟周期来度量,这一缓冲装入过程是相当耗时的。不过,当代码和数据放入了缓冲区(多次运行代码之后的结果),装入缓冲区操作所带来的失真渐渐消失。因此,实际测试时,应当抛弃前几次的数据,只计算结果稳定下来之后的平均值。

    然而,即使在看起来比较稳定的结果集中,仍会突然出现一些突变,这是由于操作系统切换线程所导致的。由于时钟计数器总是不停地累加,它的计数不能反映出代码的一部分执行时间已经用于休眠。要解决这个问题,必须将线程设置成Windows最高的优先级,即实时(对应的符号是REALTIME_PRIORITY_CLASS),防止测试期间线程被切换掉。

    但是,采用这种解决办法时必须谨慎。如果让一大段代码用这个优先级运行,可能会阻塞其他线程。因此,如果要用这种办法测试大段代码,应当确信系统暂时不作它用。另外,必须记住的是,测试完成后要把代码恢复成标准优先级——注意,是在测试完成后立即恢复,否则的话,可能带来许多风险,例如,可能直到部署应用程序时也不能再想起需要恢复优先级,由此带来的问题可能使用户久久难忘——当你的应用程序开始运行时,其他代码都好像停止运行了。

    当然,这是一个可以暂且不管的话题。无论怎样,现在我们已经有了一个高度精确的时钟,它能够在大多数当前的Intel处理器上运行,适合从Windows 95开始的所有Windows操作系统。好好享受吧!

    展开全文
  • 全网目前最好的,基于windows下写的四次握手ptp时钟同步程序,自动对时钟偏差进行修正,并计算双向延迟,实现毫秒级精度。修改时间需要提前关闭系统的自动对时功能,并用管理员方式打开程序。
  • 以来计算时效比,也就是说实际中1秒钟时间我们仿真要消耗多少实际时间,这就需要我们在程序运行前,获取一次系统时间,程序运行后,获取一次系统时间,两次相减,就是用时间。 获取时间可以用17中方法获取...

    有时候我们需要计算某次仿真的运行时间,以来计算时效比,也就是说实际中1秒钟的时间我们的仿真要消耗多少实际时间,这就需要我们在程序运行前,获取一次系统时间,程序运行后,获取一次系统时间,两次相减,就是用的时间。

    获取时间可以用17中的方法获取,但是这个函数耗时间长,而且会由于线程占用等导致获取的时间不稳定,因此我们需要一种更精确的计时方法。

    在Windows操作系统当中,QueryPerformanceFrequency()和QueryPerformanceCounter()这两个函数、精度可达到微秒级,将其单独做成了一个类,代码如下:

    头文件:

    #include<windows.h>
     
     
    classTimerCounter
    {
    public:
       TimerCounter(void);//构造函数
       ~TimerCounter(void);//析构函数
     
    private:
       LARGE_INTEGER startCount;//记录开始时间
     
       LARGE_INTEGER endCount;//记录结束时间
     
       LARGE_INTEGER freq;//本机CPU时钟频率
     
    public:
       double dbTime;//程序运行的时间保存在这里
     
    public:
       void Start();//被测程序开始点处开始计时
       void Stop();//被测程序结束点处结束计时
    };


    CPP文件

    #include "StdAfx.h"
    #include "TimerCounter.h"
    #include <iostream>
     
     
    using namespace std;
    TimerCounter::TimerCounter(void)
    {
       QueryPerformanceFrequency(&freq);//获取主机CPU时钟频率
    }
     
    TimerCounter::~TimerCounter(void)
    {
    }
     
    void TimerCounter::Start()
    {
       QueryPerformanceCounter(&startCount);//开始计时
    }
     
    void TimerCounter::Stop()
    {
       QueryPerformanceCounter(&endCount);//停止计时
     
       dbTime=((double)endCount.QuadPart-(double)startCount.QuadPart)/(double)freq.QuadPart;//获取时间差
     
    }


    测试程序如下:

    void main()
    {
        TimerCounter tc;
     
        tc.Start();
        Sleep(100);
        tc.Stop();
     
       cout<<"耗时: "<<tc.dbTime * 1000<<"ms"<<endl;
    }


    展开全文
  • Windows 2003 Server支持各种多处理器系统,同时也能在单处理器P4系统上运行。对于单处理器P4系统Windows 2003 Server将发挥出Intel超线程技术提供各种硬件线程执行引擎优势。  开发服务器应用人都...
    一、获取计时数据

      和其他Windows服务器一样,在Windows 2003 Server上最能发挥性能优势的是多线程程序。Windows 2003 Server支持各种多处理器系统,同时也能在单处理器的P4系统上运行。对于单处理器P4系统,Windows 2003 Server将发挥出Intel超线程技术提供的各种硬件线程执行引擎的优势。

      开发服务器应用的人都知道,之所以要开发并行程序,真正的原因只有一个——性能。然而,众所周知,性能改善是一个比较模糊的目标,因为多线程代码的性能通常只能靠经验估计。在单线程程序中,性能改进程度一般可以精确地预知,例如减少了多少指令和延迟较高的操作,但多线程代码不同,Windows平台中线程调度是不确定的,也就是说,在Windows中应用程序可以要求调度程序运行线程,但调度程序何时(是否)运行线程则远远超出了应用程序代码的控制范围。

      在测试性能时,开发者很快会遇到一个问题,这就是Windows内建的标准时钟实在不够精确,其可靠测量事件时间的解析度很难高于一秒,这样,要确定一个代码片段是否真正得到优化就很困难了。如果一定要用Windows的标准时钟进行测试,必须利用循环让代码运行几百万次,才能获得有效的时间数据。绝大多数情况下,使用这类循环意味着修改应用程序。

      其实,还有更好的办法,这就是Win32高解析度时钟,涉及的函数有两个:QueryPerformanceCount(),QueryPerformanceFrequency()。在Intel系统中,从P II开始,这些函数依赖于Pentium芯片内建的一个计数器。当一个Intel系统启动时,一个64位的寄存器跟踪着消逝的时钟周期,这个计数器提供了解析度极高的计时设备。

      整个64位寄存器都要用到。32 bit的整数大约能计数20亿,对于当前每秒运行20-30亿个周期的处理器,32 bit的计数器会在一秒或更少的时间内溢出,64 bit的计数器则能容纳这些秒数的20亿倍,按20亿秒计算就是约63年——可以相信,这已经远远超出测量任何程序的要求了。

      要对一个事件进行计时,只需获得事件开始之前、结束之后的时钟计数。下面的代码不依赖于Win32(即,从C/C++直接访问),稍后我们再看看操作系统提供的函数。我们首先定义一个数据结构,然后再来看填写该结构的代码:

    typedef struct _BinInt32

    {

    __int32 i32[2];

    } BigInt32;

    typedef struct _BigInt64

    {

    __int64 i64;

    } BigInt64;

    typedef union _bigInt

    { BigInt32 int32val;

     BigInt64 int64val;

    } BigInt;

    下面的代码从操作系统获得时钟计数器的高位和低位,分别填写__int64数据的两个32 bit部分:

    BigInt start_ticks, end_ticks;

    _asm {

    RDTSC

    mov start_ticks.int32val.i32[0], eax

    mov start_ticks.int32val.i32[4], edx

    }


      这段代码能够在Visual Studio .NET 2003中顺利运行,在以前的C/C++编译器中也应该没有问题。RDTSC(ReaD Time Stamp Counter)是一个汇编指令,它的功能是把时间戳计数器的内容装入EAX和EDX寄存器。执行上述代码后,start_ticks就包含了完整的时钟计数。再次调用上面的代码,把start_ticks替换成end_ticks,再从end_ticks减去start_ticks,就得到了两次调用期间流逝的时钟周期。

      要输出这个_int64值,可以使用下面的printf()掩码:

    printf ( "Function used %I64Ld ticks\n",

    end_ticks.int64val.i64 - start_ticks.int64val.i64 );


      Win32函数QueryPerformanceCounter()的功能也大致相似,它唯一的参数是一个指向计数器变量的长指针。如果函数调用失败,它返回0(实际上是FALSE)。然而,上面提供的代码突破了Windows调用的黑箱,即使在非Windows的Intel系统上,也能发挥同样的功能。

    二、使用计时数据

      如果要把时钟计数转换成时间,只要把时钟计数除以CPU的时钟频率就可以了。不过,芯片上标准的GHz数据往往与实际运行的速度不同。如果要测试芯片的实际速度,除了Win32调用QueryPerformanceFrequency(),还有几种非常好的工具软件。这里要推荐两种工具,首先是Intel自己的Processor Frequency ID Utility,可以从http://support.intel.com/support/ processors/tools/FrequencyID/FreqID.htm免费下载,它还能提供有关处理器的许多其他信息。另一个工具提供的信息更多,它就是wCPUID,可以从http://www.h-oda.com/免费下载。

      这两种工具都能够测出精确的时钟速度,用前面获得的时钟计数除以速度,就可以得到高精度的时间计数。QueryPerformanceFrequency()函数也只有一个长指针参数,出现错误时返回0或FALSE。

      在如此高的时钟解析度下,许多平常看不到的现象会显现出来。最令人莫名其妙的是,多次测试同一段代码,结果会出现很大的波动。

      大范围波动的主要原因在于读取操作,特别是第一、二两次读取与从缓冲区读取的差异。当代码第一次执行时,一般需要把它装入到缓冲区,代码所操作的数据也一样。用时钟周期来度量,这一缓冲装入过程是相当耗时的。不过,当代码和数据放入了缓冲区(多次运行代码之后的结果),装入缓冲区操作所带来的失真渐渐消失。因此,实际测试时,应当抛弃前几次的数据,只计算结果稳定下来之后的平均值。

      然而,即使在看起来比较稳定的结果集中,仍会突然出现一些突变,这是由于操作系统切换线程所导致的。由于时钟计数器总是不停地累加,它的计数不能反映出代码的一部分执行时间已经用于休眠。要解决这个问题,必须将线程设置成Windows最高的优先级,即实时(对应的符号是REALTIME_PRIORITY_CLASS),防止测试期间线程被切换掉。

      但是,采用这种解决办法时必须谨慎。如果让一大段代码用这个优先级运行,可能会阻塞其他线程。因此,如果要用这种办法测试大段代码,应当确信系统暂时不作它用。另外,必须记住的是,测试完成后要把代码恢复成标准优先级——注意,是在测试完成后立即恢复,否则的话,可能带来许多风险,例如,可能直到部署应用程序时也不能再想起需要恢复优先级,由此带来的问题可能使用户久久难忘——当你的应用程序开始运行时,其他代码都好像停止运行了。

      当然,这是一个可以暂且不管的话题。无论怎样,现在我们已经有了一个高度精确的时钟,它能够在大多数当前的Intel处理器上运行,适合从Windows 95开始的所有Windows操作系统。好好享受吧!

    转载于:https://www.cnblogs.com/junzhongxu/archive/2008/07/14/1242174.html

    展开全文
  • 修改Windows系统同步网络时间频率

    万次阅读 2017-09-05 22:11:07
    Windows系统默认时间同步间隔是7天,如果我们需要修改同步时间间隔(同步频率),我们可以通过修改注册表来手动修改它自动同步间隔以提高同步次数,保证时钟的精度,windows7,Windows8 系统: 1. 在“运行...

    Windows系统默认的时间同步间隔是7天,如果我们需要修改同步的时间间隔(同步频率),我们可以通过修改注册表来手动修改它的自动同步间隔以提高同步次数,保证时钟的精度,windows7,Windows8 系统:
    1. 在“运行”框输入“Regedit”进入注册表编辑器
    2. 展开[ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient ] 分支,并双击 SpecialPollInterval 键值,将对话框中的“基数”栏选择到“十进制”上
    3. 对话框中显示的数字正是自动对时的间隔(以秒为单位),比如默认的604800就是由7(天)×24(时)×60(分)×60(秒)计算来的。设定时间同步周期(建议设为900=15分钟或3600=1小时等周期值),填入对话框,点击确定保存关闭对话框。
    4. 展开[ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters]分支,双击NtpServer键值,修改为国家授时中心服务器的IP地址(210.72.145.44),然后点击“确定”按钮保存。

    如果使用所谓的国家授时中心服务器IP地址同步老是失败,不妨访问这个网站获取可用的域名或IP:http://www.ntp.org.cn/
    
    展开全文
  • windows系统QueryPerformanceFrequency()获取HPET(如果存在)频率,而QueryPerformanceCounter()获取HPET(如果存在高精度事件定时器(High Precision Event Timer))自上电以来时钟周期数,与CPU频率无关。...
  • 计算机网络系统 NTP时钟同步...依靠windows系统默认windows或NIST等境外时间服务器同步时间,总存在着访问堵塞、时间延迟大(同步精度低)等因素影响。现在中国国家授时中心发布了一个时间服务器地址,大家
  • 关键词:定时器 时钟 并口 数据采集引言数据采集系统在各行各业都有广泛应用。目前,已有各种各样高速、高精度、多通道数据采集卡问世。计算机通过卡上模数转换器采入数据,然后进行数据存储、数据处理和图形...
  • Windows系统默认时间同步间隔是7天,如果我们需要修改同步时间间隔(同步频率),我们可以通过修改注册表来手动修改它自动同步间隔以提高同步次数,保证时钟的精度,windows7,Windows8 系统:1. 在“运行”框...
  • windows系统QueryPerformanceFrequency()获取HPET(假设存在)频率,而QueryPerformanceCounter()获取HPET(假设存在高精度事件定时器(High Precision Event Timer))自上电以来时钟周期数,与CPU频率无关。...
  • 时间处理 在处理一些获得时间的问题时,可以用clock()函数简单的获得时钟,...1.clock(),字面精度1ms,实际精度是操作系统的时间片,windows下单核10ms,双核15ms 2.QueryPerformenceCounter,字面精度100ns(0....
  • 解决KeSetTimer定时精度不够方法

    千次阅读 2016-05-22 13:09:57
    KeSetTimer定时精度是因为windows系统的时钟分辨率仅为15ms,由于播出软件只是一个应用程序,十分依赖它的运行环境—操作系统。因此不得不提及Windows操作系统的时间片和时钟分辨率。 软件经常使用的API函数...
  • Windows下可以用系统提供API函数 QueryPerformanceFrequency 和 QueryPerformanceCounter 来进行高精度的计时,现在机器基本上都提供这种高精度的计时啦,所以不用担心。利用该函数可以精确计时到微妙...
  • 最近正在做一个嵌入式系统,是基于windows ce,外接硬件时序要微秒级延时.1.微秒级延时肯定不能基于消息(SetTimer函数),因为一出现消息堵塞等就会影响精度,而且setTimer单位才是毫秒.实际响应时间可能要到55...
  • 非实时系统精确定时器实现

    千次阅读 2016-05-10 16:58:07
    我们通常使用系统,不管是linux还是windows,都是非实时系统。非实时系统可以获得很...如果在linux或者windows系统中使用系统定时器,尽管我们可以创建精度为1ms甚至更小定时器,但是实际执行时候可以发现,定
  • 程序运行时间统计(高精度

    千次阅读 2015-06-15 18:44:48
    1 需要取得系统精确时钟函数:   1)对于一般实时控制,使用GetTickCount()函数就可以满足精度...2)这两个函数是VC提供仅供 Windows 9X使用精度时间函数,并要求计算机从硬件上支持高精度计时器。 3) Q
  • Windows熟悉人都知道,在计算机系统时间设置里,可以设置本地计算机时间与Internet时间服务器时间同步,这样计算机就会定期与网络时间进行同步,不用就担心自己计算机在经历较长时间后发生时间偏差。...
  • 用组策略配置Windows时间客户端 2009-12-15 23:09 经常我们会发现自己的计算机时间不准确 即使校对之后不长时间发现时间乂 不准确了通常这跟主板上的芯片质量有关系因为每台计算机的时钟发生器 的 精度不同对丁一般...
  • 嵌入式时间管理

    2019-09-10 14:15:33
    时间管理要提供高精度且应用可设置的系统时钟,该时钟是嵌入式系统的时基,实时系统的时钟精度一般要求... 通用操作系统的时钟精度由操作系统确定,应用不可调,且一般是几十个ms,windows系统时钟精度55MS,linux时...
  • 用组策略配置Windows时间客户端Fri,...通常这跟主板上的芯片质量有关系,因为每台计算机的时钟发生器的精度不同。对于一般人来说,如果时间差异不大,都可以接受,但是对于许多时间相关的系统来说,例如银行、电信等...
  • source:aHR0cHM6Ly95YW5kZS5yZS9wb3N0L3Nob3cvNjE5MzIw(base64)...因为计时器精确度依赖于系统时钟精度和应用从消息队列检索消息频率,计时器时间区间只能看作一个粗略值。(H1)计时器操纵应用可以使用 Se...
  • 浏览器的时钟精度就是浏览器更新时钟的频率。更新的越频繁,那么时间也就越准确。 现在浏览器的最小精度为4ms,但并不意味着频率时刻保持在4ms。仔细分析一下,“更新操作”对电脑来说是比较烧脑的,脑子稍微差点的...
  • setTimeout 0

    2015-11-13 09:14:00
    setTimeout 0 就是把事件放到下一次事件...Windows机器默认时钟精度为10-15.6毫秒(大部分情况是15.6毫秒),亦即浏览器采用的系统时钟;(function aa(){ console.log('start'); setTimeout(function(){ console.l...
  • dtwinver.zip 检测机器操作系统的版本,支持Win32s、Windows95/98、NT Workstation/Server 3.1和以后版本、Windows for Workgroups、Windows 3.0-3.11、DOS等(20KB)<END><br>37,cputicker.zip 检测Pentium CPU...
  • 1 需要取得系统精确时钟函数: ...2)这两个函数是VC提供仅供 Windows 9X使用精度时间函数,并要求计算机从硬件上支持高精度计时器。 3) QueryPerformanceFrequency()函数和 QueryPerformanceCount
  • http://zhidao.baidu.com/question/207998740.html1 需要取得系统精确时钟函数: ...2)这两个函数是VC提供仅供 Windows 9X使用精度时间函数,并要求计算机从硬件上支持高精度计时器。 3) QueryPerfor

空空如也

空空如也

1 2 3 4
收藏数 63
精华内容 25
关键字:

windows系统的时钟精度