Cython通过浮点数的最快方式,用于高频控制回路

Cython fastest way to pass a float numbers for high frequency control loops

本文关键字:方式 用于 高频 控制回路 浮点数 Cython      更新时间:2023-10-16

我在 c++ 类中有一个函数(func(,并希望从 python 端调用它以尽可能低的延迟调用以下序列:

1_on python端:func(np.array([1,2,3,4,5](或func([1,2,3,4,5](或2D数组以及您可能对降低延迟的任何其他建议。

2_on c++ 方面:我有一个 franka::RobotState robot_state_ 类型的占位符,我想在其中复制上述数组的一部分。 例如,我可以做的事情,例如:

for (int i = 0; i < 7; ++i) {
robot_state_.q     [i] = array_that_came_from_python_side  [i];
robot_state_.dq    [i] = array_that_came_from_python_side  [i+7];
robot_state_.tau_J [i] = array_that_came_from_python_side  [i+14];
}

我已经写3_Then的下一行将更新另一个类型的 franka::Torques _eff_cmd 占位符,我想返回到 python 端并想象如下:

for (int i = 0; i < 7; ++i) {
array_to_return[i] = _eff_cmd[i]
}
return array_to_return // to be sent to the python side

其中array_to_return可以在 python 端返回任何类型的类型,例如 numpy 数组或列表或任何其他建议,如输入。 然后我将在 python 端以高频率重复这个序列,因为它基本上是关于控制反馈循环的。

我的问题是如何使用 Cython 以最快的方式做到这一点,我在 C++ 端用什么定义 func。遵循此线程的一种可能提供较低延迟的方法似乎是 Memoryviews,但到目前为止,我无法很好地理解它,不知道我最好在 c++ 代码和 Cython pyx 文件中写什么。如果有人可以指导我,并且您还有其他建议,而不是memoryviews,我将不胜感激,以降低延迟

在性能优化方面,您必须进行衡量!

首先,确保您确切地知道您的热点在哪里。您可以使用perf或英特尔vTune来确保优化正确的位置。

然后,您可以为该特定热点编写google benchmark测试。

如果代码段是您的热点,拆分循环将对您有所帮助,因为您具有连续的内存访问权限。

for (int i = 0; i < 7; ++i) {
robot_state_.q    [i] = array_that_came_from_python_side  [i+7];
}
for (int i = 0; i < 7; ++i) {
robot_state_.dq     [i] = array_that_came_from_python_side  [i+7];
}
for (int i = 0; i < 7; ++i) {
robot_state_.tau_J [i] = array_that_came_from_python_side  [i+14];
}

或者它可能什么都不做,因为编译器现在非常聪明。

也许std::memcopy会做一个粘稠的工作

std::memcpy(robot_state_.q, &array_that_came_from_python_side[0], 7);
std::memcpy(robot_state_.dq, &array_that_came_from_python_side[7], 7);
std::memcpy(robot_state_.tau_J , &array_that_came_from_python_side[14], 7);