Closed tmds closed 5 years ago
@allisterb I really wonder where all those allocations come from:
using System;
class Program
{
public static readonly int MaxManagedArraySize = 2146435071;
static void Main(string[] args)
{
var managedArray = new byte[MaxManagedArraySize];
for (int i = 0; i < managedArray.Length; i++)
{
managedArray[i] = 0;
}
for (int i = 0; i <= GC.MaxGeneration; i++)
{
Console.WriteLine($"# gen {i} collections: {GC.CollectionCount(i)}");
}
}
}
outputs:
# gen 0 collections: 0
# gen 1 collections: 0
# gen 2 collections: 0
Hi, I separated the fill benchmarks into a "fill" and "create and fill" category. "Create and fill" benchmarks test how long it takes to instantiate a managed array and fill it so I'd expect there would be lots of allocations there. There shouldn't be any allocations in the "fill" category:
jembench safe --fill 10000 -i --cold-start
BenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)
Processor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8
Frequency=2531251 Hz, Resolution=395.0616 ns, Timer=TSC
.NET Core SDK=2.1.2
[Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT
Job=JemBenchmark Jit=RyuJit Platform=X64
Runtime=Core AllowVeryLargeObjects=True Toolchain=InProcessToolchain
RunStrategy=ColdStart
Method | Parameter | Mean | Error | StdDev | Allocated |
---|---|---|---|---|---|
'Fill a managed array with a single value.' | 10000 | 39.75 us | 80.83 us | 238.33 us | 240 B |
'Fill a SafeArray on the system unmanaged heap with a single value.' | 10000 | 39.62 us | 73.77 us | 217.50 us | 240 B |
'Create and Fill a managed array with a single value.' | 10000 | 22.81 us | 22.00 us | 64.88 us | 40136 B |
'Create and Fill a SafeArray on the system unmanaged heap with a single value.' | 10000 | 220.75 us | 47.79 us | 140.90 us | 208 B |
40136 B
This number makes sense. If you allocate 10000 ints, this will be about 40KB.
22.81 us
This is significantly faster than the unmanaged heap, contrary to the results on the README.md.
937.5000 | 937.5000 | 937.5000
These are the numbers I am asking about: the number of collections for 'Create and Fill a managed array with a single value'. Any thoughts on what is allocated?
It seems there was a severe bug in doing deallocation for the unmanaged buffers. This should be resolved now in the latest release. For the Fill benchmarks for SafeArrays these are the current results on my machine:
BenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)
Processor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8
Frequency=2531251 Hz, Resolution=395.0616 ns, Timer=TSC
.NET Core SDK=2.1.2
[Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT
Job=JemBenchmark Jit=RyuJit Platform=X64
Runtime=Core AllowVeryLargeObjects=True Toolchain=InProcessToolchain
RunStrategy=Throughput
Method | Parameter | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|
'Fill a managed array with a single value.' | 1000000 | 626.7 us | 5.281 us | 4.940 us | - | - | - | 256 B |
'Fill a SafeArray on the system unmanaged heap with a single value.' | 1000000 | 480.3 us | 6.787 us | 6.348 us | - | - | - | 248 B |
'Create and Fill a managed array with a single value.' | 1000000 | 1,938.7 us | 35.826 us | 33.511 us | 330.8594 | 330.8594 | 330.8594 | 4001616 B |
'Create and Fill a SafeArray on the system unmanaged heap with a single value.' | 1000000 | 607.3 us | 5.247 us | 4.908 us | - | - | - | 216 B |
You can try the latest release on your machine and let me know the results. Thanks for reporting this.
It seems there was a severe bug in doing deallocation for the unmanaged buffers. This should be resolved now in the latest release. For the Fill benchmarks for SafeArrays these are the current results on my machine: jembench safe --fill -i 1000000
BenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)
Processor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8
Frequency=2531251 Hz, Resolution=395.0616 ns, Timer=TSC
.NET Core SDK=2.1.2
[Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT
Job=JemBenchmark Jit=RyuJit Platform=X64
Runtime=Core AllowVeryLargeObjects=True Toolchain=InProcessToolchain
RunStrategy=Throughput
Method | Parameter | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|
'Fill a managed array with a single value.' | 1000000 | 626.7 us | 5.281 us | 4.940 us | - | - | - | 256 B |
'Fill a SafeArray on the system unmanaged heap with a single value.' | 1000000 | 480.3 us | 6.787 us | 6.348 us | - | - | - | 248 B |
'Create and Fill a managed array with a single value.' | 1000000 | 1,938.7 us | 35.826 us | 33.511 us | 330.8594 | 330.8594 | 330.8594 | 4001616 B |
'Create and Fill a SafeArray on the system unmanaged heap with a single value.' | 1000000 | 607.3 us | 5.247 us | 4.908 us | - | - | - | 216 B |
You can try the latest release on your machine and let me know the results. Thanks for reporting this
I'm no longer looking into this, closing.
From README:
It's surprising to see so many gen0,1,2 collections for a LOH allocation. Any idea what is being collected?
CC @mattwarren