2

これは設計上の問題です。

私は、CPU を集中的に使用するアルゴリズムを実装する Web サービスを作成することを計画していました。私が解決しようとしている問題は、python、perl、java などの高水準言語を使用すると、Web サービスを簡単に作成できるようになることです。C、C++ などの低レベル言語では、コードのパフォーマンスを微調整できます。

そこで私は、2 つの言語の橋渡しをするために何ができるかを考えていました。私が思いついたオプションは次のとおりです。

言語固有のバインディング

perl-xs または python の ctypes/loadlibrary または Java の JNI などを使用します。利点は、同じプロセスで実行できる拡張機能を作成できることです。母国語の型から C への変換とその逆の変換には、わずかなオーバーヘッドがあります。

別のデーモンを実装する

thrift / avro などを使用して、C/C++ コードを実行する別のデーモンを用意します。利点は、高水準言語から疎結合されていることです。高級言語をすぐに置き換えることができます。欠点は、シリアル化とローカル UNIX ドメイン ソケットのオーバーヘッドが、同じアドレス空間でコードを実行するよりも高くなる可能性があることです (前のオプションによって提供されます)。

皆さんはどう思いますか?

4

4 に答える 4

1

C/C++ コードが既に存在する場合は、既に持っている機能と一致する API を使用して、サービスとして公開することをお勧めします。次に、必要な API に合わせて、選択した言語で新しいサービスを記述し、C/C++ サービスを呼び出すことができます。

C/C++ コードがまだ存在せず、コードの大部分を Java や C# などの高水準言語で作成するように設定されている場合は、パフォーマンスに重要な部分を最初にその言語でも実装することを検討してください。プロファイリングによって特定のパフォーマンスの問題が示され、言語内で最も基本的な最適化手法 (最もホットなループ内での割り当てを回避するなど) を使い果たした後でのみ、最も多くのサイクルを消費することが証明されているビットを別の言語に書き直すことを検討する必要があります。 JNIなどの接着剤。

つまり、数値を手に入れるまで最適化しないでください。Java から C++ と同じパフォーマンス レベルを (ほぼ) 引き出すことができなかった根本的な理由もありません。予想よりも単純なアーキテクチャになる可能性があります。

于 2013-03-25T08:09:38.950 に答える
0

あなた自身の推論では、デーモンをより高水準の言語で実装する方が良いのではないでしょうか? ステップ 1 に戻ります。つまり、その高水準言語から C コードへのアクセスを提供する方法です。

デーモンを直接 C で書くことにした場合、大きな欠点は、実際には提供しているコア機能とは関係のないすべてのサーバー コードを維持する必要があることです。これは、デバッグするもう 1 つのことです。また、これはサービスであるため、安全に保ち、セキュリティ ホールをなくす必要もあります。

しかし、あなたが言ったように、特定の言語の拡張機能を C で書くということは、本質的にその言語に行き詰まることを意味します。右?

必ずしも。SWIG を紹介します: http://www.swig.org/

SWIG を使用すると、C コードとターゲット言語の間のインターフェイス ブリッジを作成する作業が大幅に簡素化されます。実際、私が働いているところでは、Java だけとのインターフェースにも使用しており、多言語サポートを使用することは決してありません。これは、提供されたインターフェース ファイルに基づいて定型コードを自動生成するツールです。

はい、インターフェースファイルは、学ぶべきもう1つの構文です。はい、それには限界があります。しかし、それは非常にうまく機能します。

SWIG を使用する大きな利点の 1 つは、ライブラリが単なる通常の C/C++ ライブラリであることです。コードを単純化して明確にする傾向があります。また、必要に応じて C/C++ プロジェクトでライブラリを直接使用することもできます。

于 2013-03-25T08:09:29.130 に答える
0

「シリアル化とローカル UNIX ドメイン ソケットのオーバーヘッド」は問題ではありません。デーモンと Web サービス コードの間で交換されるデータが、ネットワークを介して Web サービスからクライアントに送信されるデータとほぼ同じサイズ (またはそれよりも小さい) であると仮定すると、いずれにしてもネットワークがボトルネックになる可能性が高くなります。オーバーヘッドはほとんど測定できません。

以下は、UNIX ソケット経由で 1GB の転送をテストするためのスクリプトです (netcat-openbsd パッケージと多数のサポートを備えた bash が必要です。timeコマンドのカスタム形式から借用したタイミング コード)。

#!/bin/bash
rm -f hello.sock
nc -l -U hello.sock | wc -c &
sleep 1
T="$(date +%s%N)"
dd if=/dev/zero bs=1048576 count=1024 | nc -U hello.sock
T="$(($(date +%s%N)-T))"
echo "$T nanoseconds / GB"
rm -f hello.sock

私の Intel Core i7 システムでは、1664042362 ナノ秒/GB になります。gbit / sに変換:

(1 GB / 1664042362 ns) * (1000000000 ns / s) * (8 gbit / 1 GB) ~ 4.8 gbit / s

私のシステムでは、このベンチマークは 2 つのコアを完全に利用しています (数 GB を出力するようにプログラムを変更し、vmstat を調べることによって決定されます)。したがって、gbit/s でのインターネット接続が K であり、N 個のコアがある場合、ネットワークが完全にロードされたときに IPC によって使用される CPU の割合は次のようになります。

(K / 4.8) * (2 / N)

少なくとも 4 つのコアを使用していて、Web サービス クライアントへの帯域幅が 100 mbps 以下であり、IPC 経由で転送されるデータが、Web サービスからクライアントに転送されるデータとほぼ同じサイズかそれより小さい場合、これはうまくいきます。 IPC オーバーヘッドによって消費される CPU の 1% 以下。

于 2013-03-26T22:53:43.673 に答える
0

Mongrelを見て、Web サービスと高性能のコードを C++ で記述してください。

于 2013-03-25T08:13:33.227 に答える