ベンチマーク時にキャッシュを無効にする方法は?
-
30-09-2019 - |
質問
このコードがあります。これは、使用の順序と使用の順序を交換するときに、パフォーマンスも交換します。
using System;
using System.Diagnostics;
using System.Linq;
using System.IO;
class Test
{
const int Size = 30000000;
static void Main()
{
object[] values = new MemoryStream[Size];
UsingAs(values);
UsingCast(values);
Console.ReadLine();
}
static void UsingCast(object[] values)
{
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in values)
{
if (o is MemoryStream)
{
var m = (MemoryStream)o;
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("Cast: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
static void UsingAs(object[] values)
{
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in values)
{
if (o is MemoryStream)
{
var m = o as MemoryStream;
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("As: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
}
出力:
As: 0 : 322
Cast: 0 : 281
これをするとき...
UsingCast(values);
UsingAs(values);
...これの結果:
Cast: 0 : 322
As: 0 : 281
これをするとき...
UsingAs(values);
...これの結果:
As: 0 : 322
これを行うとき:
UsingCast(values);
...これの結果:
Cast: 0 : 322
独立して実行することは別として、方法 無効にします ベンチマークされている2番目のコードが最初のコードのキャッシュメモリを受信しないようにキャッシュは?
ベンチマークはさておき、現代のプロセッサがこのキャッシングマジックを行っているという事実を愛していました:-)
編集
このより速いコードを試してみるようにアドバイスされたように...
static void UsingAsAndNullTest(object[] values)
{
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in values)
{
var m = o as MemoryStream;
if (m != null)
{
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("As and null test: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
...結果はこれです:
As and null test: 0 : 342
上記の2つのコードよりも遅い
編集]:
それぞれのルーチンを自分のコピーに渡すようにアドバイスしたように...
static void UsingAs(object[] values)
{
object[] a = values.ToArray();
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in a)
{
if (o is MemoryStream)
{
var m = o as MemoryStream;
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("As: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
static void UsingCast(object[] values)
{
object[] a = values.ToArray();
Stopwatch sw = Stopwatch.StartNew();
int sum = 0;
foreach (object o in a)
{
if (o is MemoryStream)
{
var m = (MemoryStream)o;
sum += (int)m.Length;
}
}
sw.Stop();
Console.WriteLine("Cast: {0} : {1}", sum,
(long)sw.ElapsedMilliseconds);
}
...出力:
Cast: 0 : 282
As: 0 : 282
今、彼らは同じ結果を持っています、ありがとうRemus!
キャストを実行し、独立して、同じ結果も生成します(つまり282)。さて、なぜ彼らがなるのか もっと早く (322から282ミリ秒まで)彼らが自分の配列のコピーを手渡されたとき、私はそれから何も作ることができません:-)それは完全に別の話です
解決
写真から取り出したい場合は、L2キャッシュとTLBがミスします。同じサイズの別のメモリストリームで2番目のテストを呼び出すだけです。
所属していません StackOverflow