-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
135 lines (115 loc) · 4.47 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using System;
namespace ScatterGather
{
class Program
{
public static void Swap<T>(T[] array, int indexfirst, int indexSecond)
{
T temp = array[indexfirst];
array[indexfirst] = array[indexSecond];
array[indexSecond] = temp;
}
public static int NumberBetweenInclusive(Random random, int lowerBoundInclusive, int upperBoundInclusive)
{
int count = upperBoundInclusive - lowerBoundInclusive + 1;
return random.Next(count) + lowerBoundInclusive;
}
public static void Shuffle<T>(Random random, T[] array)
{
int lastIndex = array.Length - 1;
for (int currentIndex = 0; currentIndex < lastIndex; ++currentIndex)
{
int swapIndex = NumberBetweenInclusive(random, currentIndex, lastIndex);
Swap(array, currentIndex, swapIndex);
}
}
public static int[] GenrateRandomMap(Random random, int length)
{
var result = new int[length];
for (int i = 0; i < result.Length; ++i)
result[i] = i;
Shuffle(random, result);
return result;
}
public static int[] InvertMap(int[] array)
{
var result = new int[array.Length];
for (int i =0; i < array.Length; ++i)
{
result[array[i]] = i;
}
return result;
}
static void Scatter<T>(T[] readArray, T[] writeArray, int[] map)
{
for (int i = 0; i < writeArray.Length; ++i)
{
writeArray[map[i]] = readArray[i];
}
}
static void Gather<T>(T[] readArray, T[] writeArray, int[] map)
{
for (int i = 0; i < writeArray.Length; ++i)
{
writeArray[i] = readArray[map[i]];
}
}
static int[] GenerateRandomData(Random random, int length)
{
var result = new int[length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = random.Next();
}
return result;
}
static void ClearCache(Random random)
{
GenerateRandomData(random, 1024 * 1024 * 20 / sizeof(int));
}
static void PrintProgress(string test, int arraySize, int loopCount, long milliseconds)
{
const int millsecondsPerNano = 1000000;
System.Console.WriteLine("Time to {0, 8} {1, 10} items {2, 8} times: {3, 5}ms = {4, 5}ns per integer copy",
test,
arraySize,
loopCount,
milliseconds,
(double)milliseconds / arraySize / loopCount * millsecondsPerNano);
}
static void Main(string[] args)
{
var random = new Random();
var timer = new System.Diagnostics.Stopwatch();
System.Console.WriteLine("Press any key to exit");
while (!System.Console.KeyAvailable)
{
int arraySize = 100000000;
int loopCount = 1;
while (arraySize > 10 && !System.Console.KeyAvailable)
{
int[] writeArray = new int[arraySize];
int[] readArray = GenerateRandomData(random, arraySize);
int[] M = GenrateRandomMap(random, arraySize);
int[] MPrime = InvertMap(M);
ClearCache(random);
timer.Reset();
timer.Start();
for (int j = 0; j < loopCount; j++)
Scatter(readArray, writeArray, M);
timer.Stop();
PrintProgress("Scatter", arraySize, loopCount, timer.ElapsedMilliseconds);
ClearCache(random);
timer.Reset();
timer.Start();
for (int j = 0; j < loopCount; j++)
Gather(readArray, writeArray, MPrime);
timer.Stop();
PrintProgress("Gather", arraySize, loopCount, timer.ElapsedMilliseconds);
arraySize /= 10;
loopCount *= 10;
}
}
}
}
}