問題タブ [latency]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - あるループが別のループよりも共有メモリの更新を検出するのに時間がかかるのはなぜですか?
共有メモリに書き込む「サーバー」プログラムと、メモリから読み取るクライアント プログラムを作成しました。サーバーには、書き込み可能なさまざまな「チャネル」があります。これは、アイテムを追加しているリンクリストが異なるだけです。クライアントは、リンクされたリストのいくつかに関心があり、それらのリストに追加されたすべてのノードを、可能な限り最小限のレイテンシーで読み取りたいと考えています。
クライアントには2つのアプローチがあります。
リンクされたリストごとに、クライアントは「ブックマーク」ポインタを保持して、リンクされたリスト内の場所を維持します。リンクされたリストをラウンド ロビンし、それらすべてを何度も反復し (永遠にループします)、可能であれば各ブックマークを毎回 1 ノードずつ進めます。それができるかどうかは、ノードの「次の」メンバーの値によって決まります。null 以外の場合、次のノードへのジャンプは安全です (サーバーはそれを null から非 null にアトミックに切り替えます)。このアプローチは問題なく機能しますが、繰り返し処理するリストが多数あり、更新を受け取るリストがごくわずかである場合、レイテンシーが悪化します。
サーバーは、各リストに一意の ID を付与します。サーバーがアイテムをリストに追加するたびに、リストの ID 番号もマスターの「更新リスト」に追加します。クライアントは 1 つのブックマーク (更新リストへのブックマーク) のみを保持します。ブックマークの次のポインタが null でないかどうか ( ) を際限なくチェックし、
while(node->next_ == NULL) {}
そうである場合は先に進み、指定された ID を読み取り、その ID を持つリンク リストの新しいノードを処理します。理論的には、クライアントは毎回すべてのリストを反復処理する必要がないため、多数のリストをより適切に処理できるはずです。
両方のアプローチのレイテンシを (gettimeofday を使用して) ベンチマークしたところ、驚いたことに #2 はひどかった。最初のアプローチは、リンクされたリストの数が少ない場合、多くの場合、20us 未満のレイテンシになります。2 番目のアプローチでは、低レイテンシーの小さなスパッツがありますが、多くの場合、4,000 ~ 7,000us です。
gettimeofday をあちこちに挿入することで、アプローチ 2 で追加されたすべてのレイテンシが、次のポインターが null でないかどうかを繰り返しチェックするループで費やされていることがわかりました。これは私には不可解です。2 番目のアプローチでは、1 つのプロセスでの変更が 2 番目のプロセスに「発行」されるまでに時間がかかっているようです。ある種のキャッシュの相互作用が起こっていると思いますが、私にはわかりません。どうしたの?
更新:もともと、アプローチ#2は条件変数を使用していたため、node->next_ == NULL
条件を待機すると、サーバーは更新を発行するたびに条件を通知しました。レイテンシーは同じで、コードを上記のアプローチにまで減らした理由を理解しようとしました。マルチコア マシンで実行しているため、1 つのプロセスのスピンロックが他のプロセスに影響を与えることはありません。
更新 2: node->next_ は揮発性です。
mutex - ミューテックスまたはフューテックスのレイテンシーを測定する
ミューテックス、セマフォ、またはフューテックスのレイテンシーを測定するにはどうすればよいですか?つまり、以前にロックされたミューテックスのロックを解除することと、そのミューテックスをロックすることの2つのイベント間のレイテンシーを意味します。2つのケースがあります。すべてのスレッド/プロセスが同じCPU上にある場合(スレッドの再スケジュールにかかる時間)と、最初のスレッドが最初のCPU上にあり、2番目が2番目の場合です。
あるいは
今回は非常に短い(〜1kサイクル)ので使えませんgettimeofday()
python - サーバーのpingレイテンシの測定-Python
サーバーのIPアドレスのリストがあります。それぞれがオンラインであるかどうか、および待ち時間の長さを確認する必要があります。
これを実装する簡単な方法は見つかりませんでした。レイテンシを正確に計算するには、いくつかの問題があるようです。
何か案は?
c++ - 共有メモリからリンクリストを読み取るためのこれらの3つの方法のうち、3番目に速いのはなぜですか?
外部イベントに応答して共有メモリ内の多くのリンクリストを更新する「サーバー」プログラムがあります。クライアントプログラムがリストの更新にできるだけ早く気付くようにしたい(待ち時間が最も短い)。サーバーは、データが入力され、次のポインターが有効な場所に設定されると、リンクリストのノードをマークしstate_
ます。FILLED
それまでstate_
はですNOT_FILLED_YET
。私はメモリバリアを使用して、内部のデータが実際に準備ができている前のようにクライアントに表示state_
されないようにしています(そして、動作しているように見えますが、破損したデータは表示されません)。FILLED
また、state_
コンパイラがクライアントによるループからのチェックを解除しないようにするために、揮発性です。
サーバーコードをまったく同じに保ちながら、クライアントがリンクリストをスキャンして変更を確認するための3つの異なる方法を考え出しました。問題は、なぜ3番目の方法が最速なのかということです。
方法1:すべてのリンクリスト(「チャネル」と呼ばれる)を継続的にラウンドロビンし、ノードが「FILLED」に変更されているかどうかを確認します。
方法1では、チャネル数が少ない場合に遅延が非常に小さくなりました。しかし、チャネル数が増えると(250K以上)、すべてのチャネルをループするため、非常に遅くなりました。だから私は試しました...
方法2:各リンクリストにIDを付けます。別の「更新リスト」を横に置いておきます。リンクリストの1つが更新されるたびに、そのIDを更新リストにプッシュします。ここで、単一の更新リストを監視し、そこから取得したIDを確認する必要があります。
方法2はひどい待ち時間を与えました。方法1では10us未満の遅延が発生する可能性がありますが、方法2では不可解なことに8msの遅延が発生することがよくあります。gettimeofdayを使用すると、update_cursor-> state_の変更が、サーバーのビューからクライアントのビューに伝達するのに非常に時間がかかったようです(私はマルチコアボックスを使用しているため、遅延はキャッシュによるものと思われます)。だから私はハイブリッドアプローチを試しました...
方法3:更新リストを保持します。ただし、すべてのチャネルを継続的にループし、各反復内で更新リストが更新されているかどうかを確認します。ある場合は、番号を押し込んでください。そうでない場合は、現在繰り返しているチャネルを確認してください。
この方法の遅延は方法1と同じくらい良好でしたが、多数のチャネルにスケーリングされました。問題は、理由がわからないことです。物事にレンチを投げるだけです。「更新で見つかりました」の部分のコメントを外すと、すべてのレイテンシログメッセージの間に出力されます。つまり、更新リストでしか見つからないということです。したがって、この方法が方法2よりもどのように高速になるかわかりません。
テストデータとしてランダムな文字列を生成する完全なコンパイル可能なコード(GCCとboost-1.41が必要)は次の場所にあります:http://pastebin.com/0kuzm3Uf
更新:更新が発生するまで、3つの方法すべてが効果的にスピンロックされます。違いは、更新が行われたことに気付くのにかかる時間です。それらはすべて継続的にプロセッサに負担をかけるため、速度の違いを説明することはできません。私は他に何も実行されていない4コアのマシンでテストしているので、サーバーとクライアントは競合するものがありません。更新が条件を通知し、クライアントに条件を待機させるバージョンのコードを作成しました。これは、どのメソッドのレイテンシーにも役立ちませんでした。
Update2:3つの方法がありますが、一度に試したのは1つだけなので、state_メンバーをめぐって競合しているのは1つのサーバーと1つのクライアントだけです。
.net - .NETを使用して低速ネットワーク間でさまざまなサイズのファイルを移動するための最良の方法
さまざまなサイズ(数バイトから数百MBまで)の数千のファイルを送信する.NETリモーティングクライアント/サーバーを構築しています。これを実現するための最良の方法についてフィードバックをお願いします。私が見ているように、いくつかのオプションがあります。
- ファイル全体をリモーティングオブジェクトにシリアル化し、サイズに関係なく一度に送信します。これはおそらく最速ですが、送信中に障害が発生すると、ファイル全体を再送信する必要があり、再開する方法はありません。
- ファイルサイズが小さいもの(4KBなど)よりも大きい場合は、4KBのチャンクに分割し、それらをリモートにして、サーバーで再アセンブルします。これの複雑さに加えて、継続的なラウンドトリップと確認応答のために遅くなりますが、1つのピースの障害は多くの時間を無駄にしません。
- FTPまたはSFTPサーバーのようなものをアプリケーションに含める-クライアントはサーバーにリモート処理の使用を開始していることを通知し、ファイルをアップロードしてから、リモート処理を使用して完了を通知します。個別のFTPサービスを必要とするのではなく、アプリにすべてを含めたいのですが、必要に応じてこのオプションを利用できます。
- 障害を処理するために構築された、またはある種のチェックポイント/再開を実行できる、ある種の指定されたTCP接続またはWPFまたはその他の伝送方法を使用します。
- 私が行方不明になっている他のものはありますか?
最も柔軟で信頼性の高い伝送方法は何ですか?速度についてはそれほど心配していませんが、信頼性についてはもっと心配しています。ファイルが遅くても移動したいのです。クライアントとサーバーはマルチスレッドになるので、接続が許せば同時に複数のファイルを送信できます。
フィードバックをありがとうございます-私は人々がこれを達成する方法についていくつかの推奨事項を得るために賞金を投入します。
java - Java と C/C++ 間のプロセス間通信のための最速 (低遅延) の方法
C/C++で開発された「サーバー」にTCPソケットを介して接続するJavaアプリがあります。
アプリとサーバーの両方が同じマシン、Solaris ボックスで実行されています (ただし、最終的には Linux への移行を検討しています)。交換されるデータのタイプは単純なメッセージです (ログイン、ログイン ACK、クライアントが何かを要求し、サーバーが応答します)。各メッセージの長さは約 300 バイトです。
現在、ソケットを使用しており、すべて問題ありませんが、IPC メソッドを使用して、データを交換するためのより高速な方法 (低レイテンシー) を探しています。
私はネットを調査しており、次のテクノロジーへの参照を思いつきました。
- 共有メモリ
- パイプ
- キュー
- DMA (ダイレクト メモリ アクセス) と呼ばれるものと同様に
しかし、それぞれのパフォーマンスの適切な分析を見つけることができず、JAVA と C/C++ の両方でそれらを実装する方法 (相互に通信できるようにするため) も見つかりませんでした。
このコンテキストでの各方法のパフォーマンスと実現可能性について誰でもコメントできますか? 有用な実装情報へのポインタ/リンクはありますか?
編集・更新
ここで得たコメントと回答に続いて、Unix Domain Sockets に関する情報を見つけました。これは、パイプのすぐ上に構築されているようで、TCP スタック全体を節約してくれます。これはプラットフォーム固有なので、JNI またはjudsまたはjunixsocketでテストする予定です。
次の可能なステップは、パイプの直接実装、次に共有メモリですが、余分なレベルの複雑さについて警告されています...
ご協力いただきありがとうございます
iphone - iPhone の長い Ping 時間はアプリケーションの遅延を示していますか?
iPod Touch/iPhone/iPad がサーバー側コンポーネント (MIDI を生成し、ホスト内で送信する) と通信するリアルタイム アプリの作成を検討しています。Wifi で iPod Touch に ping を実行すると、非常に大きな遅延が発生します (そして、非常に大きな変動も):
これが iPhone->Host または Host->iPhone 時間の 2 倍であっても、15ms+ は私が検討しているアプリには長すぎます。これを回避するより速い方法はありますか (USB ケーブルなど)? そうでない場合、Android でアプリをビルドすることで他のオプションが提供されるでしょうか?
Traceroute は、より実行可能な時間を報告します。
誰かが私にとってpingとtracerouteのこの違いを解読できますか?また、ホストと(およびホストから)通信する必要があるアプリケーションにとって、それらは何を意味するのでしょうか?
performance - Linux での tcp/udp パケットの送受信におけるレイテンシの原因
Linux 2.6 で TCP/UDP パケットを送受信する際の遅延の原因は何ですか?
「ピンポン」レイテンシ テストでのレイテンシ ソースを知りたいです。
イーサネットの遅延に関するかなり優れた論文がいくつかありますが、それらはワイヤとスイッチの遅延の原因のみをカバーしています (大まかに言えば、特定のスイッチのみ)。
パケットに続く処理のステップは何ですか?
通常の ping (icmp) の詳細なレイテンシ分析に関する論文も役立ちます。
私はコミュニティに依存しています:)
networking - 「write」syscall から I/O レジスタ プログラミングまでの tcp データのデータ パス (移動)
Linux の tcp データ パスの概要はわかりますか (パスが実際に異なる場合は 2.4 ではなく 2.6)? tcp/ip スタック処理のさまざまな段階のパケットはどこにありますか?
パケットが tcp セグメントにパックされ、次に ip パケットにパックされる方法。どのようにネットワークカードに送信されますか? (一連の I/O regs 書き込みと DMA を使用して?) 「書き込み」syscall ハンドラ (いくつかの深いコールスタックを使用) でネットワーク カードに送信されますか、それとも別の瞬間に送信されますか?
performance - 1 つの双方向 TCP ソケットまたは 2 つの単方向? (Linux、大容量、低遅延)
大量のデータを定期的に送信 (交換) する必要があり、2 台のマシン間でできる限り短い待ち時間が必要です。ネットワークはかなり高速です (例: 1Gbit または 2G+)。OSはLinuxです。1 つの tcp ソケット (send と recv 用) を使用する場合と、2 つの単方向 tcp ソケットを使用する場合のどちらが高速ですか?
このタスクのテストは、NetPIPE ネットワーク ベンチマークと非常によく似ています。2^1 から 2^13 バイトまでのサイズのレイテンシと帯域幅を測定し、各サイズが少なくとも 3 回送受信されます (Teal タスクでは、送信回数がより多くなります。プロセスはおそらくピンポンのように送受信されます)。
2 つの単方向接続の利点は、Linux から得られます。
http://lxr.linux.no/linux+v2.6.18/net/ipv4/tcp_input.c#L3847
ファスト パスを無効にするその他の条件はすべて false です。そして、一方向でないソケットのみが受信時にカーネルを高速パスから停止します