2

私は HFT 取引ソフトウェアを書いています。私はすべてのマイクロ秒を気にします。今は C# で書いていますが、すぐに C++ に移行します。

そのようなコードを考えてみましょう

// Original
class Foo {
....

    // method is called from one thread only so no need to be thread-safe
    public void FrequentlyCalledMethod() {
        var actions = new List<Action>();
        for (int i = 0; i < 10; i++) {
            actions.Add(new Action(....));
        }
        // use actions, synchronous
        executor.Execute(actions);
        // now actions can be deleted
    }

超低遅延ソフトウェアは「new」キーワードをあまり使用すべきではないと思うのでactions、次のフィールドに移動しました。

// Version 1
class Foo {
....

    private List<Action> actions = new List<Action>();

    // method is called from one thread only so no need to be thread-safe
    public void FrequentlyCalledMethod() {
        actions.Clear()
        for (int i = 0; i < 10; i++) {
            actions.Add(new Action { type = ActionType.AddOrder; price = 100 + i; });
        }
        // use actions, synchronous
        executor.Execute(actions);
        // now actions can be deleted
    }

おそらく、「新しい」キーワードをまったく避けるようにする必要がありますか?事前に割り当てられたオブジェクトの「プール」を使用できます。

// Version 2
class Foo {
....

    private List<Action> actions = new List<Action>();
    private Action[] actionPool = new Action[10];

    // method is called from one thread only so no need to be thread-safe
    public void FrequentlyCalledMethod() {
        actions.Clear()
        for (int i = 0; i < 10; i++) {
            var action = actionsPool[i];
            action.type = ActionType.AddOrder;
            action.price = 100 + i;
            actions.Add(action);
        }
        // use actions, synchronous
        executor.Execute(actions);
        // now actions can be deleted
    }
  • どこまで行けばいいですか?
  • 避けることがどれほど重要newですか?
  • 構成のみが必要な事前割り当てオブジェクトを使用している間、何かを獲得できますか? (上記の例ではタイプと価格を設定)

これは超低遅延なので、可読性保守性などよりもパフォーマンスが優先されると仮定してください。

4

3 に答える 3

4

newC++ では、スコープが制限されたオブジェクトを作成する必要はありません。

void FrequentlyCalledMethod() 
{
    std::vector<Action> actions;
    actions.reserve( 10 );
    for (int i = 0; i < 10; i++) 
    {
        actions.push_back( Action(....) );
    }
    // use actions, synchronous
    executor.Execute(actions);
    // now actions can be deleted
}

Action基本クラスであり、実際の型が派生クラスの場合、ポインターまたはスマート ポインターとnewここが必要になります。ただし、 Action が具象型で、すべての要素がこの型である場合、およびこの型がデフォルトで構築可能、コピー可能、および割り当て可能である場合は必要ありません。

ただし、一般に、 new を使用しないことでパフォーマンスが向上する可能性はほとんどありません。ここ C++ では、ローカル関数スコープがオブジェクトのスコープである場合にローカル関数スコープを使用することをお勧めします。これは、C++ ではリソース管理にもっと注意を払う必要があり、それは "RAII" として知られる手法で行われるためです。これは基本的に、リソースが (オブジェクトのデストラクタを介して) どのように削除されるかを管理することを意味します。割り当てのポイント。

高いパフォーマンスは、次の方法で実現される可能性が高くなります。

  • アルゴリズムの適切な使用
  • 適切な並列処理と同期のテクニック
  • 効果的なキャッシングと遅延評価。
于 2013-01-09T17:49:26.583 に答える
2

私がHFTを嫌うのと同じくらい、私は与えられた鉄片の各糸から最大のパフォーマンスを引き出す方法をあなたに教えるつもりです。

これは、最初に作成されたプログラムが730倍高速化された例の説明です。

あなたは段階的にそれをします。各段階で、かなりの時間がかかるものを見つけて修正します。キーワードは、推測ではなく、検索です。あまりにも多くの人がコードを目で見て、役立つと思うものを修正します。多くの場合、常にではありませんが、役立つと思う人もいます。それは当て推量です。本当のスピードアップを得るには、推測できるいくつかの問題だけでなく、すべての問題を見つける必要があります。

あなたのプログラムが新しいことをしているなら、チャンスはあなたが修正する必要があるものになるある時点にあります。しかし、それだけではありません。

これがその背後にある理論です。

于 2013-01-09T18:46:00.843 に答える
0

優れた HFT ショップの高性能取引エンジンの場合、C++ コードで new/malloc を回避することが基本です。

于 2014-01-29T15:55:31.453 に答える