source: perf/stream2runs/src/driver.cxx @ 1179

Last change on this file since 1179 was 1179, checked in by ksherdy, 8 years ago

Refactor stream2runs. Extract interface methods. Remove DEFAULT compile time flag.

File size: 11.3 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <string.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <unistd.h>
8#include <sched.h>cd
9#include <iostream>
10using namespace std;
11
12// Test Repetitions
13#define RUNS 1
14
15//#define BRANCH_REDUCTION
16#include "stream2runs.h"
17
18// Performance Measurement
19#ifdef CODE_CLOCKER
20#include "../lib/cclib/cc.h"
21#include "../lib/cclib/cc.cxx"
22CC * code_clocker;
23#endif
24
25// Templated SIMD
26#define TEMPLATED_SIMD_LIB
27#include "../lib/lib_simd.h"
28
29typedef SIMD_type BytePack;
30typedef SIMD_type BitBlock;
31
32#define SIMD_REGISTER_BIT_WIDTH (sizeof(SIMD_type) << 3)
33#define REGISTER_BIT_WIDTH (sizeof(void *) << 3)
34
35// Bit stream methods
36#ifdef TEMPLATED_SIMD_LIB
37#define s2p_step(s0, s1, hi_mask, shift, p0, p1) \
38{\
39  BitBlock t0, t1;\
40  t0 = simd<16>::pack<h,h>(s0, s1);\
41  t1 = simd<16>::pack<l,l>(s0, s1);\
42  p0 = simd_if(hi_mask, t0, simd<16>::srli<shift>(t1));\
43  p1 = simd_if(hi_mask, simd<16>::slli<shift>(t0), t1);\
44}
45#endif
46#ifndef TEMPLATED_SIMD_LIB
47#define s2p_step(s0, s1, hi_mask, shift, p0, p1) \
48{\
49  BitBlock t0, t1;\
50  t0 = simd_pack_16_hh(s0, s1);\
51  t1 = simd_pack_16_ll(s0, s1);\
52  p0 = simd_if(hi_mask, t0, simd_srli_16(t1, shift));\
53  p1 = simd_if(hi_mask, simd_slli_16(t0, shift), t1);\
54}
55#endif
56
57static inline void s2p_bytepack(BytePack s[], BitBlock p[]) {
58#ifdef TEMPLATED_SIMD_LIB
59    BitBlock mask_2 = simd<2>::himask();
60    BitBlock mask_4 = simd<4>::himask();
61    BitBlock mask_8 = simd<8>::himask();
62#endif
63#ifndef TEMPLATED_SIMD_LIB
64    BitBlock mask_2 = simd_himask_2;
65    BitBlock mask_4 = simd_himask_4;
66    BitBlock mask_8 = simd_himask_8;
67#endif
68    BitBlock bit00224466_0, bit00224466_1, bit00224466_2, bit00224466_3;
69    BitBlock bit11335577_0, bit11335577_1, bit11335577_2, bit11335577_3;
70    BitBlock bit00004444_0, bit22226666_0, bit00004444_1, bit22226666_1;
71    BitBlock bit11115555_0, bit33337777_0, bit11115555_1, bit33337777_1;
72#if (BYTE_ORDER == BIG_ENDIAN)
73    s2p_step(s[0], s[1], mask_2, 1, bit00224466_0, bit11335577_0);
74    s2p_step(s[2], s[3], mask_2, 1, bit00224466_1, bit11335577_1);
75    s2p_step(s[4], s[5], mask_2, 1, bit00224466_2, bit11335577_2);
76    s2p_step(s[6], s[7], mask_2, 1, bit00224466_3, bit11335577_3);
77#endif
78#if (BYTE_ORDER == LITTLE_ENDIAN)
79    s2p_step(s[7], s[6], mask_2, 1, bit00224466_0, bit11335577_0);
80    s2p_step(s[5], s[4], mask_2, 1, bit00224466_1, bit11335577_1);
81    s2p_step(s[3], s[2], mask_2, 1, bit00224466_2, bit11335577_2);
82    s2p_step(s[1], s[0], mask_2, 1, bit00224466_3, bit11335577_3);
83#endif
84    s2p_step(bit00224466_0, bit00224466_1, mask_4, 2, bit00004444_0, bit22226666_0);
85    s2p_step(bit00224466_2, bit00224466_3, mask_4, 2, bit00004444_1, bit22226666_1);
86    s2p_step(bit11335577_0, bit11335577_1, mask_4, 2, bit11115555_0, bit33337777_0);
87    s2p_step(bit11335577_2, bit11335577_3, mask_4, 2, bit11115555_1, bit33337777_1);
88    s2p_step(bit00004444_0, bit00004444_1, mask_8, 4, p[0], p[4]);
89    s2p_step(bit11115555_0, bit11115555_1, mask_8, 4, p[1], p[5]);
90    s2p_step(bit22226666_0, bit22226666_1, mask_8, 4, p[2], p[6]);
91    s2p_step(bit33337777_0, bit33337777_1, mask_8, 4, p[3], p[7]);
92}
93
94#define double_int64_adc(x1, x2, y1, y2, rslt1, rslt2, carry) \
95  __asm__  ("sahf\n\t" \
96        "adc %[e1], %[z1]\n\t" \
97        "adc %[e2], %[z2]\n\t" \
98        "lahf\n\t" \
99     : [z1] "=r" (rslt1), [z2] "=r" (rslt2), [carryflag] "=a" (carry) \
100         : "[z1]" (x1), "[z2]" (x2), \
101           [e1] "r" (y1), [e2] "r" (y2), \
102           "[carryflag]" (carry) \
103         : "cc")
104
105#define adc128(first, second, carry, sum) \
106do\
107{\
108  union {__m128i bitblock;\
109         uint64_t int64[2];} rslt;\
110\
111  union {__m128i bitblock;\
112         uint64_t int64[2];} x;\
113\
114  union {__m128i bitblock;\
115         uint64_t int64[2];} y;\
116\
117  x.bitblock = first;\
118  y.bitblock = second;\
119\
120  double_int64_adc(x.int64[0], x.int64[1], y.int64[0], y.int64[1], rslt.int64[0], rslt.int64[1], carry);\
121  sum = rslt.bitblock;\
122}while(0)
123
124#define double_int64_sbb(x1, x2, y1, y2, rslt1, rslt2, carry) \
125  __asm__  ("sahf\n\t" \
126        "sbb %[e1], %[z1]\n\t" \
127        "sbb %[e2], %[z2]\n\t" \
128        "lahf\n\t" \
129     : [z1] "=r" (rslt1), [z2] "=r" (rslt2), [carryflag] "=a" (carry) \
130         : "[z1]" (x1), "[z2]" (x2), \
131           [e1] "r" (y1), [e2] "r" (y2), \
132           "[carryflag]" (carry) \
133         : "cc")
134
135#define sbb128(first, second, carry, sum) \
136do\
137{ union {__m128i bitblock;\
138         uint64_t int64[2];} rslt;\
139\
140  union {__m128i bitblock;\
141         uint64_t int64[2];} x;\
142\
143  union {__m128i bitblock;\
144         uint64_t int64[2];} y;\
145\
146  x.bitblock = first;\
147  y.bitblock = second;\
148\
149  double_int64_sbb(x.int64[0], x.int64[1], y.int64[0], y.int64[1], \
150                   rslt.int64[0], rslt.int64[1], carry);\
151  sum = rslt.bitblock;\
152}while(0)
153
154// Generate Comma bit streams
155static inline BitBlock bytepack2bitblock(BytePack U8[]);
156static inline BitBlock bytepack2bitblock(BytePack U8[]) {
157
158        // --- GENERATED CODE ---
159        BitBlock result;
160        BitBlock array_u8bit__5_;
161        //BitBlock AllOne = simd_const_1(1);
162        //BitBlock AllZero = simd_const_1(0);
163        BitBlock array_u8bit__2_;
164        BitBlock array_u8bit__3_;
165        BitBlock array_u8bit__4_;
166        BitBlock _strct_s2iclass__classify_bytes__temp4;
167        BitBlock _strct_s2iclass__classify_bytes__temp5;
168        BitBlock _strct_s2iclass__classify_bytes__temp2;
169        BitBlock _strct_s2iclass__classify_bytes__temp3;
170        BitBlock array_u8bit__6_;
171        BitBlock _strct_s2iclass__classify_bytes__temp1;
172        BitBlock array_u8bit__0_;
173        BitBlock array_u8bit__1_;
174        BitBlock array_u8bit__7_;       
175       
176        BitBlock u8[8];
177       
178        s2p_bytepack(U8,u8);
179        array_u8bit__0_ = u8[0];
180        array_u8bit__1_ = u8[1];
181        array_u8bit__2_ = u8[2];
182        array_u8bit__3_ = u8[3];
183        array_u8bit__4_ = u8[4];
184        array_u8bit__5_ = u8[5];
185        array_u8bit__6_ = u8[6];
186        array_u8bit__7_ = u8[7];
187
188        _strct_s2iclass__classify_bytes__temp1 = simd_or(array_u8bit__0_,array_u8bit__1_);
189        _strct_s2iclass__classify_bytes__temp2 = simd_and(array_u8bit__2_,array_u8bit__3_);
190        _strct_s2iclass__classify_bytes__temp3 = simd_andc(_strct_s2iclass__classify_bytes__temp2,_strct_s2iclass__classify_bytes__temp1);
191        _strct_s2iclass__classify_bytes__temp4 = simd_or(array_u8bit__5_,array_u8bit__6_);
192        _strct_s2iclass__classify_bytes__temp5 = simd_and(array_u8bit__4_,_strct_s2iclass__classify_bytes__temp4);     
193        result = simd_andc(_strct_s2iclass__classify_bytes__temp3,_strct_s2iclass__classify_bytes__temp5);
194       
195        return result;
196}
197
198/*
199 * Binds a process to a core - Linux specifc (sched.h).
200 */
201void SetCPUAffinity();
202void SetCPUAffinity() {
203
204        printf("Setting CPU Affinity...\n");
205       
206    cpu_set_t mask;
207    unsigned int len = sizeof(mask);
208    if (sched_getaffinity(0, len, &mask) < 0) {
209        perror("sched_getaffinity");
210    }
211
212    printf("Original CPU Affinity Mask: %08lx\n", mask.__bits[0]);
213
214    //CPU_CLR(0, &mask); // (CPU 1)
215    //CPU_CLR(1, &mask); // (CPU 0)
216
217    if (sched_setaffinity(0, len, &mask) < 0) {
218       perror("sched_setaffinity");
219    }
220
221    printf("Modified CPU Affinity Mask: %08lx\n", mask.__bits[0]);
222} 
223
224int main(int argc, char * argv[]) {
225
226  if (argc < 2) {
227    printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
228          exit(-1);
229  }
230  char * filename = argv[1];
231
232  FILE *infile, *outfile;
233  infile = fopen(filename, "rb");
234  if (!infile) {
235      fprintf(stderr, "Error: cannot open %s for input.\n", filename);
236      exit(-1);
237  }
238
239  if (argc < 3) outfile = stdout;
240  else {
241    outfile = fopen(argv[2], "wb");
242    if (!outfile) {
243      fprintf(stderr, "Error: cannot open %s for writing.\n", argv[2]);
244      exit(-1);
245    }
246  }
247
248#ifdef CODE_CLOCKER
249    SetCPUAffinity();
250        char * src_filename = argv[1];
251        char * cmdline = new char[strlen(argv[0]) + strlen(argv[1]) +1 +1]; 
252        strcat(cmdline, argv[0]);
253        strcat(cmdline," ");
254        strcat(cmdline,argv[1]); 
255       
256        #define NUM_EVENTS 2
257        // PAPI_TOT_CYC 0x8000003b  Yes   No   Total cycles
258        // PAPI_L1_DCM  0x80000000  Yes   No   Level 1 data cache misses
259        // PAPI_L2_DCM  0x80000002  Yes   Yes  Level 2 data cache misses
260        // PAPI_L3_DCM  0x80000004  No    No   Level 3 data cache misses
261        // PAPI_BR_CN   0x8000002b  Yes   No   Conditional branch instructions
262        // PAPI_BR_TKN  0x8000002c  Yes   No   Conditional branch instructions taken
263        // PAPI_BR_NTK  0x8000002d  Yes   Yes  Conditional branch instructions not taken
264        // PAPI_BR_MSP  0x8000002e  Yes   No   Conditional branch instructions mispredicted
265        // PAPI_BR_PRC  0x8000002f  Yes   Yes  Conditional branch instructions correctly predicted
266       
267        int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
268        int cal_size = 1000;
269        code_clocker = new CC(Events,NUM_EVENTS,cal_size);
270        code_clocker->set_cmd(cmdline);
271#endif 
272       
273  struct stat st;
274  stat(filename, &st);
275  int filesize = st.st_size;
276  size_t bytes = filesize;
277 
278  bytes += sizeof(SIMD_type);
279 
280  // allocate a byte buffer and pad with sizeof(SIMD_type) trailing zeroes
281  unsigned char * byte_buffer = (unsigned char *)simd_new(bytes);
282     
283  // slurp a source file into a byte buffer
284  int chars_read = fread(byte_buffer, sizeof(char), filesize, infile);
285  while(chars_read > 0) {
286          chars_read = fread(byte_buffer+chars_read, sizeof(char), filesize, infile);
287  }
288 
289  // mask trailing zeroes
290  memset(byte_buffer + filesize, 0, sizeof(SIMD_type)); 
291 
292  // allocate bit stream buffer
293  int simd_packs = bytes/sizeof(SIMD_type);
294 
295  #ifdef BRANCH_REDUCTION
296    BitBlock * bit_stream_buffer = simd_new(simd_packs + 1); // pad at least an additional general width of bytes
297  #else   
298    BitBlock * bit_stream_buffer = simd_new(simd_packs);   
299  #endif
300 
301  if(bit_stream_buffer == NULL) {
302      fprintf(stderr, "Error: out of memory.\n");
303      exit(-1);   
304  }
305
306  cout << "Source bytes: " << filesize << endl;
307  cout << "Allocate bytes: " << bytes << endl;
308  cout << "SIMD packs: " << simd_packs << endl; 
309  cout << "SIMD pack bytes: " << simd_packs * sizeof(SIMD_type) << endl << endl;
310 
311  #ifdef CODE_CLOCKER
312        code_clocker->start_interval();
313  #endif       
314               
315  // convert byte packs to bit streams
316  for(int i=0,j=0;i<simd_packs;i++,j+=SIMD_REGISTER_BIT_WIDTH) {
317          bit_stream_buffer[i] = bytepack2bitblock((BytePack *)(&byte_buffer[j]));
318  }
319
320  size_t max_span_count = simd_packs * SIMD_REGISTER_BIT_WIDTH /2;     
321  size_t * starts = new size_t[max_span_count];
322  size_t * lengths = new size_t[max_span_count];
323  size_t span_count = 0;
324
325  size_t general_register_blocks;
326               
327  #ifdef BRANCH_REDUCTION
328        general_register_blocks = simd_packs * sizeof(SIMD_type);       
329        stream2runs((unsigned char *)bit_stream_buffer, general_register_blocks, starts, lengths, &span_count); // reduce bit stream butt
330  #else 
331        general_register_blocks = simd_packs * SIMD_REGISTER_BIT_WIDTH / REGISTER_BIT_WIDTH;
332        stream2runs((size_t *)bit_stream_buffer, general_register_blocks, starts, lengths, &span_count);       
333  #endif
334
335  #ifdef CODE_CLOCKER
336        code_clocker->end_interval(bytes);
337  #endif       
338
339  printf("(pos,lgth) = span_value\n");
340  for(int i =0; i<span_count; i++) {
341        printf("(%zu,%zu) = ", starts[i], lengths[i]);
342        print_chars(((char *) byte_buffer) + starts[i], lengths[i]);     
343  }     
344  printf("\n");
345               
346  delete [] starts;
347  delete [] lengths;
348 
349  if(byte_buffer != NULL) {
350          simd_delete((SIMD_type *)byte_buffer);
351  }
352 
353  if(bit_stream_buffer != NULL) {
354          simd_delete(bit_stream_buffer);
355  }
356
357  if(infile != NULL) {
358          fclose(infile);
359  }
360 
361  if(argc > 3) {
362          fclose(outfile);
363  }
364 
365  #ifdef CODE_CLOCKER
366        code_clocker->write_xml_file();
367        code_clocker->display_system_info();
368        code_clocker->display_raw_event_data();
369        delete code_clocker; 
370  #endif
371       
372  fprintf(stdout, "Done.\n");
373 
374  return(0);
375}
376
377
378
Note: See TracBrowser for help on using the repository browser.