3

タイム クリティカルなロボット工学アプリケーションのために、ループ内にある関数呼び出しを最適化する必要があります。私のスクリプトは Python で書かれており、ctypes を介して私が書いた C++ ライブラリとやり取りし、マイクロコントローラ ライブラリを呼び出します。

ボトルネックは、位置-速度-時間ポイントをマイクロコントローラーのバッファーに追加することです。私のタイミング チェックによると、ctypes を介した C++ 関数の呼び出しには約0.45数秒かかり、C++ 側では呼び出された関数に0.17数秒かかります。どうにかしてこの差を縮める必要があります。

関連する python コードは次のとおりです。データはポイントの 2D 配列であり、ライブラリは 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 コードをコンパイルする必要はありません。

4

3 に答える 3

1

Python と C++ 間の往復は、特にctypes (通常の C/Python ラッパーの解釈されたバージョンのようなもの) を使用する場合、コストがかかる可能性があります。

目標は、移動の回数を最小限に抑え、移動ごとに可能な限り多くの作業を行うことです。

コードの粒度が細かすぎるように見えます (つまり、旅行が多すぎて、各旅行での作業が少なすぎます)。

numpyパッケージは、そのデータを C/C++ に直接公開できます。これにより、高価な Python オブジェクトのボックス化とボックス化解除 (付随するメモリ割り当てを伴う) を回避でき、一度に 1 点ずつではなく、データ ポイントの範囲を渡すことができます。

呼び出しごとに 1 回ではなく、一度に多くのポイントを処理するように C++ コードを変更します ( sqlite3モジュールがexecuteと executemanyで行うのと同じように)。

于 2013-04-21T22:39:00.217 に答える
0

あなたはただ使うことができますdata_np.data.tobytes()

data_np = np.vstack([nodes, positions, velocities, times]).transpose().astype(np.long)
timer = time()
clibrary.addPvtAll(N, data_np.data.tobytes())
print("clibrary.addPvtAll() call: %f" % (time() - timer))
于 2013-04-27T23:39:52.953 に答える