我必须执行一个时间紧迫且简单的操作(比方说一个简单的缓冲区移位)。我正在使用 C++ 和
Eigen
库。
平均时间还可以,完全符合我的要求。问题是,同样的操作有时会花费更多的时间。假设我仍然可以容忍长达 100us,但以上所有内容都有可能为实时应用程序带来协调和同步问题(即使这种情况只发生三四次)。
完全意识到CPU不适合用于时间关键的实时操作,有没有什么方法可以进一步减少这种情况的发生并使执行时间变平,至少有一个确定性的方法来解决该项目? 这是一个非常简单且有代表性的测试:
#include <Eigen/Dense>
#include <complex>
#include <vector>
#include <chrono>
#include <algorithm>
#include <iostream>
#include<numeric>
#include<cnpy.h>
#include <Windows.h>
#include <filesystem>
#define DATA_DIR "C:/workspace/trash"
#define NOW std::chrono::steady_clock::now
#define DELTA_T_US(t0, t1) (float)(std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0).count() / 1000.0)
void print_time_res(std::vector<float> vec, std::string title)
{
auto _min = *std::min_element(vec.begin(), vec.end());
auto _max = *std::max_element(vec.begin(), vec.end());
auto _avg = std::accumulate(vec.begin(), vec.end(), 0.0) / vec.size();
std::cout << title << " minimum ex time : " << _min << "us" << std::endl;
std::cout << title << " maximum ex time : " << _max << "us" << std::endl;
std::cout << title << " average ex time : " << _avg << "us" << std::endl;
std::cout << std::endl;
}
typedef std::complex<float> std_complex;
typedef float complex[2];
typedef Eigen::Array <std_complex, Eigen::Dynamic, 1> eigen_c_vec;
typedef Eigen::Array<float, Eigen::Dynamic, 1> eigen_vec;
int main()
{
// NOTE: Requires Administrator privileges! Otherwise it will fall back to priority "High". Checked with Task Manager
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
// Needed for other operations
printf("SIMD Used by Eigen: %s\n", Eigen::SimdInstructionSetsInUse());
eigen_vec vec = eigen_vec::Random(360);
const int N = 10000000;
std::vector<float> times(N);
for (int i = 0; i < N; i++)
{
auto _then = NOW();
// Vector shifting
vec(Eigen::seqN(0, 360 - 30)) = vec(Eigen::seqN(30, 360 - 30)).eval();
auto _now = NOW();
// Measured in microseconds
times[i] = DELTA_T_US(_then, _now);
}
times.pop_back();
print_time_res(times, "Eigen shifting");
// Just to plot with Python
std::string filename = (std::filesystem::path(DATA_DIR) / "TimeData.npy").string();
cnpy::npy_save(filename, times, "w");
return 0;
}
CMake 列表:
add_executable(EigenTest src/EigenTest.cpp)
target_link_libraries(EigenTest PRIVATE Eigen3::Eigen cnpy::cnpy)
target_compile_options(EigenTest PUBLIC /arch:AVX2)
结果
SIMD Used by Eigen: AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2
Eigen shifting minimum ex time : 0us
Eigen shifting maximum ex time : 143us
Eigen shifting average ex time : 0.0956169us
另一件需要考虑的事情是桌面操作系统用来提高前台应用程序及其窗口的响应能力的优先级提升概念。您可以尝试更改 CPU 调度程序以支持后台服务,看看是否有帮助。
此外,禁用所有视觉效果,使用支持硬件加速GPU调度的显卡(显卡驱动程序是高DPC延迟的主要原因之一),并禁用所有不必要的后台进程、服务和计划任务以及设置高性能电源方案和在 BIOS 中禁用 CPU 睡眠状态都应该有助于最大限度地减少延迟并提供更一致的结果。
使用不带 GUI 的 Windows Server 来运行应用程序也是一种选择,就像在没有网络和音频适配器的计算机上运行应用程序一样。
这就是 Windows 所能做的一切,Windows 从来就不是用来作为实时操作系统的,而是从协作多任务模型开始的。