Skip to content

Commit

Permalink
Stop consuming result of GetPinnedReference() (#1280)
Browse files Browse the repository at this point in the history
* Stop consuming pinned references

We were consuming the values returned from `GetPinnedReference()` API, however
`.Consume()` uses `volatile` and that introduces memory barriers for ARM64.
Since we just want to measure the performance of `GetPinnedReference()` it is
unnecessary to introduce a differentiating factor for 1 architecture and not the
other. Hence I have removed the `.Consume()` and instead just storing the returned
result in a variable.

Before:
```asm
...
G_M52573_IG23:
        79400063          ldrh    w3, [x3]
        D5033BBF          dmb     ish
        79008023          strh    w3, [x1,#64]
        D2800003          mov     x3, #0
        34000040          cbz     w0, G_M52573_IG25
                                                ;; bbWeight=1    PerfScore 15.50
G_M52573_IG24:
        AA0203E3          mov     x3, x2
                                                ;; bbWeight=0.25 PerfScore 0.13
G_M52573_IG25:
        79400063          ldrh    w3, [x3]
        D5033BBF          dmb     ish
        79008023          strh    w3, [x1,#64]
        D2800003          mov     x3, #0
        34000040          cbz     w0, G_M52573_IG27
                                                ;; bbWeight=1    PerfScore 15.50
G_M52573_IG26:
        AA0203E3          mov     x3, x2
                                                ;; bbWeight=0.25 PerfScore 0.13
...

```

After
```asm
...
G_M51552_IG23:
        79400021          ldrh    w1, [x1]
        D2800001          mov     x1, #0
        34000040          cbz     w0, G_M51552_IG25
                                                ;; bbWeight=1    PerfScore 4.50
G_M51552_IG24:
        AA0203E1          mov     x1, x2
                                                ;; bbWeight=0.25 PerfScore 0.13
G_M51552_IG25:
        79400021          ldrh    w1, [x1]
        D2800001          mov     x1, #0
        34000040          cbz     w0, G_M51552_IG27
                                                ;; bbWeight=1    PerfScore 4.50
G_M51552_IG26:
        AA0203E1          mov     x1, x2
                                                ;; bbWeight=0.25 PerfScore 0.13
...

```

This change reduces the ARM64 numbers for this benchmark from 10ns to 1ns. I am not sure if
we should just add `Consume()` method and mark it as `NoInline`. That's what is done for
`System.Memory.Span<T>.GetPinnedReference()` benchmark.
  • Loading branch information
kunalspathak authored Apr 15, 2020
1 parent 71a3bf4 commit a6955b7
Showing 1 changed file with 22 additions and 14 deletions.
36 changes: 22 additions & 14 deletions src/benchmarks/micro/libraries/System.Memory/ReadOnlySpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,33 @@ namespace System.Memory
public class ReadOnlySpan
{
private readonly string _sampeString = "this is a very nice sample string";
private readonly Consumer _consumer = new Consumer();

[Benchmark]
public ReadOnlySpan<char> StringAsSpan() => _sampeString.AsSpan();

[Benchmark(OperationsPerInvoke = 16)]
public void GetPinnableReference()
[Benchmark(OperationsPerInvoke = 16 * 2)]
public char GetPinnableReference()
{
ReadOnlySpan<char> span = _sampeString.AsSpan();
var consumer = _consumer;

consumer.Consume(span.GetPinnableReference()); consumer.Consume(span.GetPinnableReference());
consumer.Consume(span.GetPinnableReference()); consumer.Consume(span.GetPinnableReference());
consumer.Consume(span.GetPinnableReference()); consumer.Consume(span.GetPinnableReference());
consumer.Consume(span.GetPinnableReference()); consumer.Consume(span.GetPinnableReference());
consumer.Consume(span.GetPinnableReference()); consumer.Consume(span.GetPinnableReference());
consumer.Consume(span.GetPinnableReference()); consumer.Consume(span.GetPinnableReference());
consumer.Consume(span.GetPinnableReference()); consumer.Consume(span.GetPinnableReference());
consumer.Consume(span.GetPinnableReference()); consumer.Consume(span.GetPinnableReference());
char c;

c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
c = span.GetPinnableReference(); c = span.GetPinnableReference();
return c;
}

[Benchmark(OperationsPerInvoke = 16)]
Expand Down Expand Up @@ -97,4 +105,4 @@ private static string GenerateInputString(char source, int count, char replaceCh
return new string(str);
}
}
}
}

0 comments on commit a6955b7

Please sign in to comment.