How to invalidate cache when benchmarking?

我怕爱的太早我们不能终老 提交于 2019-12-04 05:25:14

问题


I have this code, that when swapping the order of UsingAs and UsingCast, their performance also swaps.

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);
    }


}

Outputs:

As: 0 : 322
Cast: 0 : 281

When doing this...

UsingCast(values);
UsingAs(values);

...Results to this:

Cast: 0 : 322
As: 0 : 281

When doing just this...

UsingAs(values);

...Results to this:

As: 0 : 322

When doing just this:

UsingCast(values);

...Results to this:

Cast: 0 : 322

Aside from running them independently, how to invalidate the cache so the second code being benchmarked won't receive the cached memory of first code?

Benchmarking aside, just loved the fact that modern processors do this caching magic :-)

[EDIT]

As advised to try this faster code(supposedly)...

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);
}

...The result is this:

As and null test: 0 : 342

Slower than the two codes above

[EDIT]:

As advised to hand each routine their own copy...

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);
}

...Outputs:

Cast: 0 : 282
As: 0 : 282

Now they have the same results, thanks Remus!

Running Cast and As independently, they also yield the same result(i.e. 282). Now, as for why they become faster (from 322 down to 282 milliseconds) when they are handed their own copy of array, I can't make anything out of it :-) That's entirely another story


回答1:


If you want to take out of the picture the L2 cache and the TLB misses then simply call the second test on a different MemoryStream of the same size.



来源:https://stackoverflow.com/questions/2680035/how-to-invalidate-cache-when-benchmarking

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!