6

クライアント側コードの一部のパフォーマンスを測定するために、マルチスレッド コードでincrementAndGetメソッドを使用しています。AtomicLong

@Override
public void run() {


   long start = System.nanoTime();

   attributes = client.getAttributes(columnsList);

   long end = System.nanoTime() - start;

   final AtomicLong before = select.putIfAbsent(end / 1000000L, new AtomicLong(1L));
        if (before != null) {
            before.incrementAndGet();
        }
}

上記のコードでは、時間を測定しようとしています-

client.getAttributes(columnsList);

とっている。

私の知る限り、incrementAndGetメソッドは現在の値をアトミックに 1 ずつ増やします。これは、各スレッドが他のスレッドが値をインクリメントするのを待つ可能性があることを意味します。私は正しいですか?ブロックされるということでしょうか?

また、これはメソッドのパフォーマンスを測定する方法にも影響しますか? その測定にも余分な時間が追加されるということですか?

私がこれを尋ねている理由は、クライアント側コードとサーバー側コードのほとんどをベンチマークしようとしているからです。各メソッドにかかる時間を測定する必要がある場合は、次のように単純に実行しています-

測定したいコードが何であれ、通常はそのメソッドのすぐ上に以下の行を置きます

long start = System.nanoTime();

そして、これらの2行は同じ方法の後にありますが、ConcurrentHashMap

long end = System.nanoTime() - start;

final AtomicLong before = select.putIfAbsent(end / 1000000L, new AtomicLong(1L));
    if (before != null) {
        before.incrementAndGet();
    }

メソッドを使用しincrementAndGetていて、パフォーマンス測定に余分な時間を追加している場合、正確な結果が得られない可能性がありますか?

アップデート:-

これは以下の方法で、 で行ったときに取得しF3ましincrementAndGeteclipse

ここに同期ブロックがあります。つまり、各スレッドはここで他のスレッドを待機します。そして、それはブロッキングコールです。

/**
 * Atomically increments by one the current value.
 *
 * @return the updated value
 */
public final synchronized long incrementAndGet() {                          //IBM-perf_AtomicLong
   ++value;                                                                 //IBM-perf_AtomicLong
   return value;                                                            //IBM-perf_AtomicLong
}

ああ。JVM を確認したところ、IBM JVMと比較して実行されていSUN JVMます。私はこの特定のことを変えることができない会社で働いているので.

このロックベースのソリューションを回避して、メソッドのパフォーマンス/ベンチマークを測定する方法はありますか? 私は IBM JVM を実行していることに留意してください。

助けてくれてありがとう。

4

1 に答える 1

8

心配しないでください。あなたが外国為替プラットフォームか何かのようなものを書いていない限り、その小さな、小さな待ち時間は問題ではありません. アイデアを提供するために、私たちはナノ秒のオーダーで話しますが、アプリケーション コードでは通常ミリ秒で話します。さらに、JVM のロックが大幅に改善されました。競合が少ない場合 (これが標準です)、ロック ベースのソリューションと非ブロッキング ソリューションのパフォーマンスの違いはごくわずかです。

しかし驚くべきことに、IBM JVM は AtomicLong にロックを使用します。すべての主要な実装はノンブロッキング CAS を使用していると思いました。CAS を使用する一般的な実装を次に示します。

/**
 * Atomically increments by one the current value.
 *
 * @return the updated value
 */
public final long incrementAndGet() {
    for (;;) {
        long current = get();
        long next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}

フォローアップ コメントへ
の対応: 非常に大まかな経験則として、現在のエンド ツー エンドの応答時間 (または応答時間の要件) が 30 ミリ秒を超えている場合、long をインクリメントするのに時間がかかったとしても、私はこれについて心配する必要はありません。ナノ秒の領域になります。より多くの改善が得られる最適化する場所が他にあることはほぼ確実です (例: ミリ秒)。

ただし、AtomicLong の Sun JVM 実装をコピーして、代わりにノンブロッキング実装を使用することもできます。IBM VM にも CAS 操作が必要なためです。これは、中程度から高い競合 (多数のスレッド) が予想される場合にのみ、大幅な改善をもたらす可能性があります。そうでない場合、ロック ソリューションは現在の改善されたロックの実装 (思い出すと JDK6 から利用可能) とほぼ同じように実行できると思います。

実際、競合が非常に多い場合、ロックはノンブロッキング ソリューションよりも優れたパフォーマンスを発揮します。したがって、理想的には2つの実装を使用して結果を比較する必要があります...これが、気にするべきではないと私が思う理由です.ここで取り組むことで達成できる改善の mil 倍になります。

于 2013-04-14T00:29:41.413 に答える