SetThreadAffinityMask用途

通过调用SetThreadAffinityMask,就能为各个线程设置亲缘性屏蔽: 


  DWORD_PTR  SetThreadAffinityMask  ( 
      HANDLE  hThread,                                  //  handle  to  thread 
      DWORD_PTR  dwThreadAffinityMask    //  thread  affinity  mask 
  ); 
  该函数中的  hThread  参数用于指明要限制哪个线程,  dwThreadAffinityMask用于指明该线程 
  能够在哪个CPU上运行。dwThreadAffinityMask必须是进程的亲缘性屏蔽的相应子集。返回值 
  是线程的前一个亲缘性屏蔽。例如,可能有一个包含4个线程的进程,它们在拥有4个CPU的计算机上运行。如果这些线程中的一个线程正在执行非常重要的操作,而你想增加某个CPU始终可供它使用的可能性,为此你对其他3个线程进行了限制,使它们不能在CPU  0上运行,而只能在CPU  1、2和3上运行。因此,若要将3个线程限制到CPU  1、2和3上去运行,可以这样操作: 
   
  //线程0只能在cpu  0上运行 
  SetThreadAffinityMask(hThread0,0x00000001); 
  //线程1,2,3只能在cpu  1,2,3上运行 
  SetThreadAffinityMask(hThread1,0x0000000E); 
  SetThreadAffinityMask(hThread2,0x0000000E); 
  SetThreadAffinityMask(hThread3,0x0000000E); 

<think>好的,用户之前已经问过关于使用C++的chrono库来计算帧频的问题,现在他们想了解如何使用Windows特定的高精度计时函数QueryPerformanceFrequency和QueryPerformanceCounter来实现同样的目标。我需要确保回答与他们之前的查询一致,同时提供针对这些特定API的详细步骤。 首先,用户可能是在Windows平台上开发,需要更底层的控制或更高的精度,而chrono可能在他们的环境中不够。他们可能已经尝试过之前的方案,但需要更直接的Windows API方法,或者可能在阅读某些资料时看到了这两个函数,想了解如何正确使用。 接下来,我需要详细解释这两个函数的作用。QueryPerformanceFrequency获取计时器的频率,而QueryPerformanceCounter获取当前的计数值。通过两次Counter的差值除以Frequency得到时间间隔,进而计算帧频。 用户可能对如何正确获取这两个值以及处理可能的性能问题有疑问。我需要确保代码示例清晰,包括如何初始化和使用这些函数,并强调类型转换的重要性,避免整数溢出,比如使用LARGE_INTEGER结构体来存储大整数。 另外,用户可能希望了解如何定期输出帧频,所以需要展示一个循环结构,在其中计算每一帧的时间,并在达到一定时间间隔(比如每秒)时计算并输出FPS。同时,提到重置计数器和时间的步骤,以确保准确的平均值计算。 还要考虑用户可能需要优化或平滑帧频显示,所以可以建议使用滑动平均或环形缓冲区来平滑结果,减少波动。这部分在之前的回答中已经提到过,可以在这里再次提及,但需要调整以适应Windows API的实现。 需要注意的常见错误包括忘记初始化Frequency,或者在计算时间差时没有处理足够的精度。同时,需要提醒用户避免使用clock()函数,因为它的精度和用途不符合需求,而Windows的这两个函数更适合高精度计时。 最后,确保回答结构清晰,分步骤说明,代码示例正确,并涵盖注意事项和优化技巧,帮助用户全面理解如何有效使用这些函数来计算帧频。</think>在Windows平台下使用`QueryPerformanceFrequency()`和`QueryPerformanceCounter()`实现帧频计算,可按以下步骤操作: --- ### 一、基础实现原理 1. **硬件计数器原理** - `QueryPerformanceFrequency()`:获取高精度计时器的频率(单位:计数次数/秒) - `QueryPerformanceCounter()`:获取当前计数器的值(无单位整数值) - 时间间隔计算公式:$时间差 = \frac{结束计数 - 开始计数}{频率}$ --- ### 二、完整代码实现 ```cpp #include <windows.h> #include <iostream> int main() { LARGE_INTEGER frequency; LARGE_INTEGER start_counter, end_counter; double delta_time = 0.0; int frame_count = 0; double total_time = 0.0; // 获取计时器频率(只需初始化一次) QueryPerformanceFrequency(&frequency); // 返回值为BOOL,实际开发中应检查 // 主循环前记录初始时间 QueryPerformanceCounter(&start_counter); LARGE_INTEGER last_report = start_counter; while (true) { // 替换为实际运行条件 // 1. 执行帧逻辑(如渲染、计算等) // 2. 获取结束时间 QueryPerformanceCounter(&end_counter); // 3. 计算时间差(秒) delta_time = static_cast<double>(end_counter.QuadPart - start_counter.QuadPart) / frequency.QuadPart; // 4. 更新统计量 total_time += delta_time; frame_count++; // 5. 定期输出(每秒) LARGE_INTEGER current_time = end_counter; double elapsed_since_report = static_cast<double>(current_time.QuadPart - last_report.QuadPart) / frequency.QuadPart; if (elapsed_since_report >= 1.0) { double fps = frame_count / elapsed_since_report; std::cout << "FPS: " << fps << std::endl; // 重置计数器 frame_count = 0; last_report = current_time; } // 6. 准备下一帧 start_counter = end_counter; } return 0; } ``` --- ### 三、关键优化建议 1. **类型处理优化** ```cpp // 使用QuadPart处理64位整型,避免32位溢出 __int64 counter_diff = end_counter.QuadPart - start_counter.QuadPart; ``` 2. **精度控制**(显示小数点后两位) ```cpp #include <iomanip> std::cout << std::fixed << std::setprecision(2) << "FPS: " << fps << "\n"; ``` 3. **平滑处理方案** ```cpp // 使用加权平均(EMA) const double alpha = 0.2; static double smoothed_fps = 0.0; smoothed_fps = alpha * fps + (1 - alpha) * smoothed_fps; ``` --- ### 四、性能对比表格 | 计时方法 | 典型精度 | 平台限制 | CPU消耗 | |-------------------------|--------------|-------------|--------| | QueryPerformanceCounter | 100纳秒 | Windows专用 | 低 | | std::chrono | 微秒级 | 跨平台 | 中 | | timeGetTime() | 1毫秒 | Windows专用 | 最低 | --- ### 五、注意事项 1. **错误处理** ```cpp if (!QueryPerformanceFrequency(&frequency)) { std::cerr << "High-resolution counter not supported!" << std::endl; return -1; } ``` 2. **多核同步问题**(某些旧硬件可能不同核心的计数器不同步): ```cpp SetThreadAffinityMask(GetCurrentThread(), 1); // 绑定到首个CPU核心 ``` 3. **长期运行防溢出**: - `QuadPart`为64位整数,按3GHz频率计算可连续运行约292年才会溢出 --- ### 六、替代方案(Windows专属API) ```cpp // 更高精度的多媒体计时器(需包含<mmsystem.h>) timeBeginPeriod(1); // 设置最小计时精度为1ms DWORD start_time = timeGetTime(); // ... 计算时间差 ... timeEndPeriod(1); // 必须成对调用 ``` 这种实现方式特别适合需要精确到微秒级控制的Windows平台应用,如游戏开发、实时数据采集等场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值