2 * Copyright 2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and
30 * documentation are those of the authors and should not be
31 * interpreted as representing official policies, either expressed
32 * or implied, of GRNET S.A.
38 #include <sys/syscall.h>
39 #include <sys/types.h>
41 #include <xseg/xseg.h>
46 #include <bench-xseg.h>
52 #define likely(x) __builtin_expect(!!(x),1)
53 #define unlikely(x) __builtin_expect(!!(x),0)
56 #define unlikely(x) (x)
66 * LFSRs are pseudo-random number generators. They are deterministic (meaning
67 * that the same seed will produce the same number sequence) and extremely
70 * You can find more about LFSRs from these links:
71 * http://en.wikipedia.org/wiki/Linear_feedback_shift_register
72 * http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
73 * http://www.ti.com/lit/an/scta036a/scta036a.pdf
74 * http://notabs.org/lfsr/lfsr.html
75 * http://www.electricdruid.net/index.php?page=techniques.practicalLFSRs
77 * LFSR taps retrieved from:
78 * http://home1.gte.net/res0658s/electronics/LFSRtaps.html
80 * It's common in the bibliography to start the numbering of LFSR bits from 1
81 * instead of 0. We will use the same numbering in this code and alter it
84 * Below is a 64x6 uint8_t array that covers all the appropriate taps for
85 * maximal length LFSRs, ranging from 3-bits to 64bit. It's memory overhead
86 * should be relatively small, no more than 384 bytes.
88 static uint8_t taps[64][MAX_TAPS] =
90 {0}, {0}, {0}, //LFSRs with less that 3-bits cannot exist
91 {3, 2}, //Tap position for 3-bit LFSR
92 {4, 3}, //Tap position for 4-bit LFSR
93 {5, 3}, //Tap position for 5-bit LFSR
94 {6, 5}, //Tap position for 6-bit LFSR
95 {7, 6}, //Tap position for 7-bit LFSR
96 {8, 6, 5 ,4}, //Tap position for 8-bit LFSR
97 {9, 5}, //Tap position for 9-bit LFSR
98 {10, 7}, //Tap position for 10-bit LFSR
99 {11, 9}, //Tap position for 11-bit LFSR
100 {12, 6, 4, 1}, //Tap position for 12-bit LFSR
101 {13, 4, 3, 1}, //Tap position for 13-bit LFSR
102 {14, 5, 3, 1}, //Tap position for 14-bit LFSR
103 {15, 14}, //Tap position for 15-bit LFSR
104 {16, 15, 13, 4}, //Tap position for 16-bit LFSR
105 {17, 14}, //Tap position for 17-bit LFSR
106 {18, 11}, //Tap position for 18-bit LFSR
107 {19, 6, 2, 1}, //Tap position for 19-bit LFSR
108 {20, 17}, //Tap position for 20-bit LFSR
109 {21, 19}, //Tap position for 21-bit LFSR
110 {22, 21}, //Tap position for 22-bit LFSR
111 {23, 18}, //Tap position for 23-bit LFSR
112 {24, 23, 22, 17}, //Tap position for 24-bit LFSR
113 {25, 22}, //Tap position for 25-bit LFSR
114 {26, 6, 2, 1}, //Tap position for 26-bit LFSR
115 {27, 5, 2, 1}, //Tap position for 27-bit LFSR
116 {28, 25}, //Tap position for 28-bit LFSR
117 {29, 27}, //Tap position for 29-bit LFSR
118 {30, 6, 4, 1}, //Tap position for 30-bit LFSR
119 {31, 28}, //Tap position for 31-bit LFSR
120 {32, 31, 29, 1}, //Tap position for 32-bit LFSR
121 {33, 20}, //Tap position for 33-bit LFSR
122 {34, 27, 2, 1}, //Tap position for 34-bit LFSR
123 {35, 33}, //Tap position for 35-bit LFSR
124 {36, 25}, //Tap position for 36-bit LFSR
125 {37, 5, 4, 3, 2, 1},//Tap position for 37-bit LFSR
126 {38, 6, 5, 1}, //Tap position for 38-bit LFSR
127 {39, 35}, //Tap position for 39-bit LFSR
128 {40, 38, 21, 19}, //Tap position for 40-bit LFSR
129 {41, 38}, //Tap position for 41-bit LFSR
130 {42, 41, 20, 19}, //Tap position for 42-bit LFSR
131 {43, 42, 38, 37}, //Tap position for 43-bit LFSR
132 {44, 43, 18, 17}, //Tap position for 44-bit LFSR
133 {45, 44, 42, 41}, //Tap position for 45-bit LFSR
134 {46, 45, 26, 25}, //Tap position for 46-bit LFSR
135 {47, 42}, //Tap position for 47-bit LFSR
136 {48, 47, 21, 20}, //Tap position for 48-bit LFSR
137 {49, 40}, //Tap position for 49-bit LFSR
138 {50, 49, 24, 23}, //Tap position for 50-bit LFSR
139 {51, 50, 36, 35}, //Tap position for 51-bit LFSR
140 {52, 49}, //Tap position for 52-bit LFSR
141 {53, 52, 38, 37}, //Tap position for 53-bit LFSR
142 {54, 53, 18, 17}, //Tap position for 54-bit LFSR
143 {55, 31}, //Tap position for 55-bit LFSR
144 {56, 55, 35, 34}, //Tap position for 56-bit LFSR
145 {57, 50}, //Tap position for 57-bit LFSR
146 {58, 39}, //Tap position for 58-bit LFSR
147 {59, 58, 38, 37}, //Tap position for 59-bit LFSR
148 {60, 59}, //Tap position for 60-bit LFSR
149 {61, 60, 46, 45}, //Tap position for 61-bit LFSR
150 {62, 61, 6, 5}, //Tap position for 62-bit LFSR
151 {63, 62}, //Tap position for 63-bit LFSR
155 * There are two kinds of LFSRs, each of which can be implemented with XOR or
157 * a) Fibonacci LFSRs, that have XOR/XNOR gates serially to produce the input
159 * b) Galois LFSRs, that have XOR/XNOR gates parallely, separated from one
160 * another and the outputs of which are fed as input bits. Also, the tap bits
161 * are flipped, depending on the output bit.
163 * A Galois LFSR seems more complicated but is actually the fittest
164 * implementation for an LFSR on CPU, due to the fact that the input bit can
165 * be computed on one turn, instead of 2 - 6 that would be needed for a
166 * Fibonacci LFSR. Another point that must be taken into consideration is
167 * that an LFSR with XOR gates has the 0 state as illegal, which is something
168 * we do not want for benchmarks.
170 * That's why we use an Galois-XNOR LFSR.
172 * Below we create what can best be described as an XNOR-mask
174 static uint64_t lfsr_create_xnormask(uint8_t *taps)
177 uint64_t xnormask = 0;
179 for(i = 0; i < MAX_TAPS && taps[i] != 0; i++)
180 xnormask |= 1UL << (taps[i] - 1);
186 * To initialize an LFSR we need the following:
187 * a) the upper limit of random numbers that we want LFSR to generate (size)
188 * b) the initial state of LFSR (seed)
190 * NOTE1: If the upper limit is bigger than 63 bits or smaller than 3 bits, we
191 * cannot create the LFSR.
192 * NOTE2: If 2^(n+1) < upper_limit <= 2^n , the LFSR that will be created will
194 * NOTE3: If an LFSR has n bits, the seed must not be all ones (= 2^(n+1) - 1)
197 int lfsr_init(struct lfsr *lfsr, uint64_t size, uint64_t seed)
203 //i has number of bits of size
204 for (i = 0; size; i++)
211 lfsr->xnormask = lfsr_create_xnormask(taps[i]);
213 if (seed == (1UL << (i + 1)) - 1)
220 int lfsr_init(struct lfsr *lfsr, uint64_t size, uint64_t seed)
226 //i has number of bits of size
227 for (i = 0; size; i++)
230 //Too small or too big size to create an LFSR out of it
234 //The all ones state is illegal. Due to the fact that our seed is
235 //nanoseconds taken from clock_gettime, we are sure that the 31st bit will
236 //always be 0. The following codes has that in mind and creates a seed
237 //that has at least one 0.
238 if (seed == UINT64_MAX) {
240 lfsr->state = global_seed >> (31 - i);
242 lfsr->state = global_seed << (i - 31);
248 lfsr->cached_bit = 1UL << (i-1);
250 lfsr->xnormask = lfsr_create_xnormask(taps[i]);
257 * Sanity-check every LFSR for mistakes.
259 static int lfsr_check()
264 uint64_t upper_limit;
266 //Create all LFSRs with maximum limit
267 for (length = 3; length < 64; length++) {
268 if (lfsr_init(&lfsr, pow(2, length) - 1, 1))
270 // printf("XNOR-mask: %lu, state: %lu, limit: %lu\n",
271 // lfsr.xnormask, lfsr.state, lfsr.limit);
272 period = 1; //Already initialized at 1
273 upper_limit = pow(2, length);
275 while(likely(period++ < upper_limit))
278 if (lfsr.state == 1) {
279 printf("%u-bit LFSR is correct\n", length);
282 printf("%u-bit LFSR did not iterate successfully\n", length);
283 printf("Current tap positions: ");
284 for (i = 0; i < MAX_TAPS && taps[length][i] != 0; i++)
285 printf("%u ", taps[length][i]);