Skip to content

Commit aa4aa07

Browse files
authored
block sketch (#271)
* block * cleanup * fix xml doc warning * block2 * tests * rem thru * runner * segblock * stackalloc * seg block avx * reconcile * use segment * cleanup * remarks * cleanup2
1 parent cf0f625 commit aa4aa07

File tree

7 files changed

+220
-140
lines changed

7 files changed

+220
-140
lines changed

BitFaster.Caching.Benchmarks/Lfu/SketchFrequency.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ namespace BitFaster.Caching.Benchmarks.Lfu
1111
[HideColumns("Job", "Median", "RatioSD", "Alloc Ratio")]
1212
public class SketchFrequency
1313
{
14-
const int iterations = 512;
15-
private static CmSketch<int, DisableHardwareIntrinsics> std = new CmSketch<int, DisableHardwareIntrinsics>(10, EqualityComparer<int>.Default);
16-
private static CmSketch<int, DetectIsa> avx = new CmSketch<int, DetectIsa>(10, EqualityComparer<int>.Default);
14+
const int sketchSize = 1_048_576;
15+
const int iterations = 1_048_576;
16+
17+
private static CmSketch<int, DisableHardwareIntrinsics> std = new CmSketch<int, DisableHardwareIntrinsics>(sketchSize, EqualityComparer<int>.Default);
18+
private static CmSketch<int, DetectIsa> avx = new CmSketch<int, DetectIsa>(sketchSize, EqualityComparer<int>.Default);
1719

1820
[GlobalSetup]
1921
public void Setup()
@@ -28,16 +30,24 @@ public void Setup()
2830
}
2931
}
3032

31-
[Benchmark(Baseline = true)]
32-
public bool EstimateFrequency()
33+
[Benchmark(Baseline = true, OperationsPerInvoke = iterations)]
34+
public int EstimateFrequency()
3335
{
34-
return std.EstimateFrequency(1) > std.EstimateFrequency(2);
36+
int count = 0;
37+
for (int i = 0; i < iterations; i++)
38+
count += std.EstimateFrequency(i) > std.EstimateFrequency(i + 1) ? 1: 0;
39+
40+
return count;
3541
}
3642

37-
[Benchmark()]
38-
public bool EstimateFrequencyAvx()
43+
[Benchmark(OperationsPerInvoke = iterations)]
44+
public int EstimateFrequencyAvx()
3945
{
40-
return avx.EstimateFrequency(1) > avx.EstimateFrequency(2);
46+
int count = 0;
47+
for (int i = 0; i < iterations; i++)
48+
count += avx.EstimateFrequency(i) > avx.EstimateFrequency(i + 1) ? 1 : 0;
49+
50+
return count;
4151
}
4252
}
4353
}

BitFaster.Caching.Benchmarks/Lfu/SketchIncrement.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ namespace BitFaster.Caching.Benchmarks.Lfu
1111
[HideColumns("Job", "Median", "RatioSD", "Alloc Ratio")]
1212
public class SketchIncrement
1313
{
14-
const int iterations = 1024;
15-
private static CmSketch<int, DisableHardwareIntrinsics> std = new CmSketch<int, DisableHardwareIntrinsics>(10, EqualityComparer<int>.Default);
16-
private static CmSketch<int, DetectIsa> avx = new CmSketch<int, DetectIsa>(10, EqualityComparer<int>.Default);
14+
const int sketchSize = 1_048_576;
15+
const int iterations = 1_048_576;
16+
private static CmSketch<int, DisableHardwareIntrinsics> std = new CmSketch<int, DisableHardwareIntrinsics>(sketchSize, EqualityComparer<int>.Default);
17+
private static CmSketch<int, DetectIsa> avx = new CmSketch<int, DetectIsa>(sketchSize, EqualityComparer<int>.Default);
1718

18-
[Benchmark(Baseline = true)]
19+
[Benchmark(Baseline = true, OperationsPerInvoke = iterations)]
1920
public void Inc()
2021
{
2122
for (int i = 0; i < iterations; i++)
@@ -24,7 +25,7 @@ public void Inc()
2425
}
2526
}
2627

27-
[Benchmark()]
28+
[Benchmark(OperationsPerInvoke = iterations)]
2829
public void IncAvx()
2930
{
3031
for (int i = 0; i < iterations; i++)

BitFaster.Caching.ThroughputAnalysis/Runner.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public static void Run(Mode mode, int cacheSize)
2424

2525
private static void RunTest(Mode mode, int cacheSize)
2626
{
27+
Console.WriteLine();
2728
Console.WriteLine("Generating input distribution...");
2829

2930
var (bench, dataConfig, capacity) = ConfigFactory.Create(mode, cacheSize, maxThreads);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+

2+
using System.Runtime.Intrinsics.X86;
3+
using Xunit;
4+
5+
namespace BitFaster.Caching.UnitTests
6+
{
7+
public static class Intrinsics
8+
{
9+
public static void SkipAvxIfNotSupported<I>()
10+
{
11+
// when we are trying to test Avx2, skip the test if it's not supported
12+
Skip.If(typeof(I) == typeof(DetectIsa) && !Avx2.IsSupported);
13+
}
14+
}
15+
}

BitFaster.Caching.UnitTests/Lfu/CmSketchTests.cs

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11

2+
using System.Collections.Generic;
23
using BitFaster.Caching.Lfu;
34
using FluentAssertions;
4-
using System.Collections.Generic;
5-
using System.Runtime.Intrinsics.X86;
65
using Xunit;
76

87
namespace BitFaster.Caching.UnitTests.Lfu
@@ -23,9 +22,24 @@ public abstract class CmSketchTestBase<I> where I : struct, IsaProbe
2322

2423
public CmSketchTestBase()
2524
{
26-
SkipAvxIfNotSupported();
25+
Intrinsics.SkipAvxIfNotSupported<I>();
26+
}
27+
28+
[SkippableFact]
29+
public void Repro()
30+
{
31+
sketch = new CmSketch<int, I>(1_048_576, EqualityComparer<int>.Default);
32+
33+
for (int i = 0; i < 1_048_576; i++)
34+
{
35+
if (i % 3 == 0)
36+
{
37+
sketch.Increment(i);
38+
}
39+
}
2740
}
2841

42+
2943
[SkippableFact]
3044
public void WhenCapacityIsZeroDefaultsSelected()
3145
{
@@ -100,10 +114,48 @@ public void WhenClearedCountIsReset()
100114
sketch.EstimateFrequency(2).Should().Be(0);
101115
}
102116

103-
private static void SkipAvxIfNotSupported()
117+
[SkippableFact]
118+
public void HeavyHitters()
104119
{
105-
// when we are trying to test Avx2, skip the test if it's not supported
106-
Skip.If(typeof(I) == typeof(DetectIsa) && !Avx2.IsSupported);
120+
for (int i = 100; i < 100_000; i++)
121+
{
122+
sketch.Increment(i);
123+
}
124+
for (int i = 0; i < 10; i += 2)
125+
{
126+
for (int j = 0; j < i; j++)
127+
{
128+
sketch.Increment(i);
129+
}
130+
}
131+
132+
// A perfect popularity count yields an array [0, 0, 2, 0, 4, 0, 6, 0, 8, 0]
133+
int[] popularity = new int[10];
134+
135+
for (int i = 0; i < 10; i++)
136+
{
137+
popularity[i] = sketch.EstimateFrequency(i);
138+
}
139+
140+
for (int i = 0; i < popularity.Length; i++)
141+
{
142+
if ((i == 0) || (i == 1) || (i == 3) || (i == 5) || (i == 7) || (i == 9))
143+
{
144+
popularity[i].Should().BeLessThanOrEqualTo(popularity[2]);
145+
}
146+
else if (i == 2)
147+
{
148+
popularity[2].Should().BeLessThanOrEqualTo(popularity[4]);
149+
}
150+
else if (i == 4)
151+
{
152+
popularity[4].Should().BeLessThanOrEqualTo(popularity[6]);
153+
}
154+
else if (i == 6)
155+
{
156+
popularity[6].Should().BeLessThanOrEqualTo(popularity[8]);
157+
}
158+
}
107159
}
108160
}
109161
}

0 commit comments

Comments
 (0)