【发布时间】:2013-04-14 17:15:47
【问题描述】:
我需要针对时间关键型机器人应用程序优化循环中的函数调用。我的脚本在 python 中,它通过 ctypes 与我编写的 C++ 库进行交互,然后调用微控制器库。
瓶颈是向微控制器缓冲区添加位置-速度-时间点。根据我的时间检查,通过 ctypes 调用 C++ 函数大约需要 0.45 秒,而在 C++ 端,被调用函数需要 0.17 秒。我需要以某种方式减少这种差异。
这里是相关的 python 代码,其中数据是一个二维点数组,而库是通过 ctypes 加载的:
data_np = np.vstack([nodes, positions, velocities, times]).transpose().astype(np.long)
data = ((c_long * 4) * N)()
for i in range(N):
data[i] = (c_long * 4)(*data_np[i])
timer = time()
clibrary.addPvtAll(N, data)
print("clibrary.addPvtAll() call: %f" % (time() - timer))
这里是被调用的 C++ 函数:
void addPvtAll(int N, long data[][4]) {
clock_t t0, t1;
t0 = clock();
for(int i = 0; i < N; i++) {
unsigned short node = (unsigned short)data[i][0];
long p = data[i][1];
long v = data[i][2];
unsigned char t = (unsigned char)data[i][3];
VCS_AddPvtValueToIpmBuffer(device(node), node, p, v, t, &errorCode);
}
t1 = clock();
printf("addPvtAll() call: %f \n", (double(t1 - t0) / CLOCKS_PER_SEC));
}
我不是绝对需要使用 ctypes,但我不想每次运行 Python 代码时都必须编译它。
【问题讨论】:
-
是C++主程序,调用Python代码,还是Python主程序,调用C++代码。如果主程序是 Python,您应该通过扩展库调用 C++,例如 Python/C API、SWIG、PyCXX 或 Boost.Python。您还可以使用 Cython,它可以让您从 Python 调用 C/C++ 代码。
-
主程序是Python。但是,我不想每次运行 Python 时都必须编译它,理想情况下也不必重写整个 C++ 库。你建议研究哪一个?
-
Boost.Python 和 SWIG 涉及编写包装器,而不是重写代码。 SWIG 有时会生成丑陋的代码,而 Boost.Python 在 64 位平台上会出现问题。如果您确实使用 Boost.Python,请创建一个 32 位 Linux 虚拟机来运行它。SWIG 使用提供的接口文件自动生成一个包装器。 PyCXX 看起来有点奇怪,但很有希望。你最好的选择是 SWIG 和 Boost.Python。它们都不需要重写。
标签: c++ python optimization ctypes