PCとZYNQ Linux間のTCP/IP通信プログラム(2)
このようなアーキテクチャになると、TCP/IP越しに行われる操作はレジスタリードやレジスタライトといったプリミティブな操作なので、プロトコル的には、
こんなやりとりを何度も何度も繰り返すわけです。1回の計測で数十回の操作が生じるとは思うのですが、細かいパケットをどのくらいの速さで投げ合えるかということがレスポンスを左右するポイントになります。
単純に実験してみた感じでは16バイト小分けにしてsend()関数を呼んでも、実際に送出されるときには複数個まとめられて1500バイトくらいのパケットになってしまってよくわからないので、
とやってNagelのアルゴリズムがOFFになって1個1個のパケットで出ていくかと思ってやってみたのですが、少しはバラけたものの完全に1個1個分離されることはありませんでした。
サーバ側でrecvしておいて何かのコマンドを受け取ったらsendで返す。クライアント側ではsendして、recvで何かを受信したら次にsendをする、というプログラムを組んで実験してみました。
その結果、
TCP dumpで見てみると、だいたい1ミリ秒で1.5~2往復くらい出来ているようです。つまり毎秒1500~2000回のレジスタリード/ライトができるようです。
もちろん地球の裏にあるようなCosmoZを操作するなら重くなるかもしれませんが、同一ネットワーク内にあるZynq Linuxを操作するなら十分な速度が出ているといえます。
あと、send関数などのmanか何かで読んだのですが、write-write-readのプロトコルを作るのは推奨されないとのことでした。TCP/IPの送信制御タイミングの問題で待ち時間が生じるようです。
レジスタライトのようにレスポンスがいらない操作の場合にまさにこの状況が発生します。レジスタライトだと、PCからZYNQへアドレスとデータをパケットを送るだけでよく応答を見る必要はないのですが、その後にレジスタリードを行うとwrite-write-readになってしまいます。これをするとものすごく遅くなります。30回の操作で1秒くらいの待ち時間が生じていたような気がします。レジスタライトに0000とかダミーの応答を返すようにしたら驚くほど速くなりました。
こういったAPIやプロトコルを設計する場合は、応答が必要のないコマンドでも何らかの応答を返すようにしないといけないようですね。
| 固定リンク
コメント