Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 绩效衡量:时间与刻度?_C++_Multithreading_Performance - Fatal编程技术网

C++ 绩效衡量:时间与刻度?

C++ 绩效衡量:时间与刻度?,c++,multithreading,performance,C++,Multithreading,Performance,在1个或2个内核上运行2线程程序时,确保实现实时性能的最佳方法是什么?boost::定时器还是RDTSC? 我们从那个代码开始 boost::timer t; p.f(frame); max_time_per_frame = std!::max(max_time_per_frame, t.ellapsed()); ... where p is an instance of Proc. class Proc { public: Proc() : _frame_counter(0) {}

在1个或2个内核上运行2线程程序时,确保实现实时性能的最佳方法是什么?boost::定时器还是RDTSC?

我们从那个代码开始

boost::timer t;
p.f(frame);
max_time_per_frame = std!::max(max_time_per_frame, t.ellapsed());

... where p is an instance of Proc.

class Proc {
public:
    Proc() : _frame_counter(0) {}

    // that function must be call for each video frame and take less than 1/fps seconds 
    // 24 fps => 1/24 => < 0.04 seconds.
    void f(unsigned char * const frame) 
    {
        processFrame(frame); //that's the most important part

        //that part run every 240 frame and should not affect
        // the processFrame flow !
        if(_frame_counter % 240 == 0) 
        {
            do_something_more();
        }
        _frame_counter++;
    }

private:
    _frame_counter;
}
我总是在1核和2核上开始我的程序。因此我使用
start/AFFINITY 1pro.exe
start/AFFINITY 3prog.exe
从时间的角度来看,一切正常,
max\u time\u per\u frame
低于我们的目标,接近0.02秒/帧的平均值

但是如果我使用RDTSC转储在f中花费的滴答数

#include <intrin.h>
...
unsigned long long getTick()
{
    return __rdtsc();
}

void f(unsigned char * const frame) 
{
    s = getTick();

    processFrame(frame); //that's the most important part

    //that part run every 240 frame and should not affect
    // the processFrame flow !
    if(_frame_counter % 240 == 0) 
    {
        sem.up();
    }
    _frame_counter++;

    e = getTick();
    dump(e - s);
}
#包括
...
无符号long-long-getTick()
{
返回uu rdtsc();
}
void f(无符号字符*常量帧)
{
s=getTick();
processFrame(frame);//这是最重要的部分
//该部分每240帧运行一次,不应影响
//流程框架流!
如果(_帧_计数器%240==0)
{
sem.up();
}
_帧计数器++;
e=getTick();
垃圾场(e-s);
}
start/AFFINITY 3 prog.exe
max_tick_per_frame是稳定的,正如预期的那样,我看到1个线程(1个核心的100%),第2个线程以正常速度在第2个核心上启动

start/AFFINITY 1 pro.exe
,我只看到了一个100%的内核(正如预期的那样),但是
do\u something\u more
计算时间似乎并没有随着时间的推移而延长,交错线程执行。事实上,每隔一段时间,我就看到了蜱虫数量的大幅增加


那么问题是为什么?唯一有趣的度量是时间吗?
勾选
在单核上运行软件(频率提升)时是否有意义?

尽管在windows之外永远无法获得真正的实时性能,但您可以通过使用

下面是一个利用API的小代码块

#include <Windows.h>
#include <stdio.h>

int
main(int argc, char* argv[])
{
    double timeTaken;
    LARGE_INTEGER frequency;
    LARGE_INTEGER firstCount;
    LARGE_INTEGER endCount;
    /*-- give us the higheest priority avaliable --*/
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    /*-- get the frequency of the timer we are using --*/
    QueryPerformanceFrequency(&frequency);  
    /*-- get the timers current tick --*/
    QueryPerformanceCounter(&firstCount);
    /*-- some pause --*/
    Sleep(1);
    /*-- get the timers current tick --*/
    QueryPerformanceCounter(&endCount);
    /*-- calculate time passed --*/
    timeTaken = (double)(doubleendCount.QuadPart-firstCount.QuadPart)/(double)(frequency.QuadPart/1000);

    printf("Time: %lf", timeTaken);

    return 0;
}
#包括
#包括
int
main(int argc,char*argv[])
{
双倍时间;
大整数频率;
大整数firstCount;
大整数结束计数;
/*--给我们最高的优先权--*/
SetThreadPriority(GetCurrentThread(),线程优先级时间临界);
/*--获取我们正在使用的计时器的频率--*/
QueryPerformanceFrequency(&frequency);
/*--获取计时器当前的滴答声--*/
QueryPerformanceCounter(&firstCount);
/*--停顿一下--*/
睡眠(1);
/*--获取计时器当前的滴答声--*/
QueryPerformanceCounter(&endCount);
/*--计算经过的时间--*/
所用时间=(double)(doubleendCount.QuadPart firstCount.QuadPart)/(double)(frequency.QuadPart/1000);
printf(“时间:%lf”,耗时);
返回0;
}
您还可以使用:

#include <Mmsystem.h>
if(timeBeginPeriod(1) == TIMERR_NOCANDO) {
    printf("TIMER could not be set to 1ms\n");
}
/*-- your code here --*/
timeEndPeriod(1);
#包括
if(timeBeginPeriod(1)=TIMERR\u NOCANDO){
printf(“计时器无法设置为1ms\n”);
}
/*--你的代码在这里--*/
timeEndPeriod(1);

但这会将全局windows计时器分辨率更改为您将其设置为(或至少尝试设置)的时间间隔,因此,除非您100%确定自己是唯一使用此程序的人,否则我不会推荐这种方法,因为这可能会对其他程序产生意外的副作用。

尽管在windows之外您永远无法获得真正的实时性能,但您可以通过使用

下面是一个利用API的小代码块

#include <Windows.h>
#include <stdio.h>

int
main(int argc, char* argv[])
{
    double timeTaken;
    LARGE_INTEGER frequency;
    LARGE_INTEGER firstCount;
    LARGE_INTEGER endCount;
    /*-- give us the higheest priority avaliable --*/
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    /*-- get the frequency of the timer we are using --*/
    QueryPerformanceFrequency(&frequency);  
    /*-- get the timers current tick --*/
    QueryPerformanceCounter(&firstCount);
    /*-- some pause --*/
    Sleep(1);
    /*-- get the timers current tick --*/
    QueryPerformanceCounter(&endCount);
    /*-- calculate time passed --*/
    timeTaken = (double)(doubleendCount.QuadPart-firstCount.QuadPart)/(double)(frequency.QuadPart/1000);

    printf("Time: %lf", timeTaken);

    return 0;
}
#包括
#包括
int
main(int argc,char*argv[])
{
双倍时间;
大整数频率;
大整数firstCount;
大整数结束计数;
/*--给我们最高的优先权--*/
SetThreadPriority(GetCurrentThread(),线程优先级时间临界);
/*--获取我们正在使用的计时器的频率--*/
QueryPerformanceFrequency(&frequency);
/*--获取计时器当前的滴答声--*/
QueryPerformanceCounter(&firstCount);
/*--停顿一下--*/
睡眠(1);
/*--获取计时器当前的滴答声--*/
QueryPerformanceCounter(&endCount);
/*--计算经过的时间--*/
所用时间=(double)(doubleendCount.QuadPart firstCount.QuadPart)/(double)(frequency.QuadPart/1000);
printf(“时间:%lf”,耗时);
返回0;
}
您还可以使用:

#include <Mmsystem.h>
if(timeBeginPeriod(1) == TIMERR_NOCANDO) {
    printf("TIMER could not be set to 1ms\n");
}
/*-- your code here --*/
timeEndPeriod(1);
#包括
if(timeBeginPeriod(1)=TIMERR\u NOCANDO){
printf(“计时器无法设置为1ms\n”);
}
/*--你的代码在这里--*/
timeEndPeriod(1);

但这会将全局windows计时器分辨率更改为您将其设置为(或至少尝试设置)的时间间隔,因此,除非您100%确定您是唯一使用此程序的人,否则我不会推荐这种方法,因为这可能会对其他程序产生意外的副作用。

基于对REALTIME\u PRIORITY\u类的评论,我在测试程序中添加了以下行

#define NOMINMAX
#include <windows.h>
....

SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
通过这一更改,我获得了我期望的调度和RDTSC值,而无需配置优先级


感谢所有的帮助和建议。

基于对REALTIME_PRIORITY_类的评论,我在测试程序中添加了以下行

#define NOMINMAX
#include <windows.h>
....

SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
通过这一更改,我获得了我期望的调度和RDTSC值,而无需配置优先级


感谢所有的帮助和建议。

我刚刚回答了一个类似的问题:我是在看到有人提到.exe文件扩展名时发表这一评论的。如果您不使用Windows,我深表歉意。简单地说,你不能-MS Windows不是实时操作系统(RTOS)-你可以接近,但Windows永远不会实时。@zaufi,看起来很相似,但我的结果是相反的,在1核或2核上运行软件并不会真正改变
时间
,但是在1核上运行/调度2线程时,
tick
的数量在一帧内增加,而不是在几帧内增加,比如在下一帧的实时处理过程中,额外的线程执行时间没有分散/交错。您是否意识到即使在实时操作系统上,RDTSC也存在许多问题?我不认为这是一个很好的选择时间任何东西,即使在非常规范