source: trunk/lib/stream2runs/src/driver.cxx @ 1229

Last change on this file since 1229 was 1229, checked in by vla24, 8 years ago

Reorganized SymbolTable? library

File size: 11.5 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>
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
154void print_chars(const char * str, size_t length);
155void print_chars(const char * str, size_t length) {
156
157        for(int i=0;i<length;i++) {
158                printf("%c",str[i]);
159        }
160        printf("\n");
161       
162}
163
164// Generate Comma bit streams
165static inline BitBlock bytepack2bitblock(BytePack U8[]);
166static inline BitBlock bytepack2bitblock(BytePack U8[]) {
167
168        // --- GENERATED CODE ---
169        BitBlock result;
170        BitBlock array_u8bit__5_;
171        //BitBlock AllOne = simd_const_1(1);
172        //BitBlock AllZero = simd_const_1(0);
173        BitBlock array_u8bit__2_;
174        BitBlock array_u8bit__3_;
175        BitBlock array_u8bit__4_;
176        BitBlock _strct_s2iclass__classify_bytes__temp4;
177        BitBlock _strct_s2iclass__classify_bytes__temp5;
178        BitBlock _strct_s2iclass__classify_bytes__temp2;
179        BitBlock _strct_s2iclass__classify_bytes__temp3;
180        BitBlock array_u8bit__6_;
181        BitBlock _strct_s2iclass__classify_bytes__temp1;
182        BitBlock array_u8bit__0_;
183        BitBlock array_u8bit__1_;
184        BitBlock array_u8bit__7_;       
185       
186        BitBlock u8[8];
187       
188        s2p_bytepack(U8,u8);
189        array_u8bit__0_ = u8[0];
190        array_u8bit__1_ = u8[1];
191        array_u8bit__2_ = u8[2];
192        array_u8bit__3_ = u8[3];
193        array_u8bit__4_ = u8[4];
194        array_u8bit__5_ = u8[5];
195        array_u8bit__6_ = u8[6];
196        array_u8bit__7_ = u8[7];
197
198        _strct_s2iclass__classify_bytes__temp1 = simd_or(array_u8bit__0_,array_u8bit__1_);
199        _strct_s2iclass__classify_bytes__temp2 = simd_and(array_u8bit__2_,array_u8bit__3_);
200        _strct_s2iclass__classify_bytes__temp3 = simd_andc(_strct_s2iclass__classify_bytes__temp2,_strct_s2iclass__classify_bytes__temp1);
201        _strct_s2iclass__classify_bytes__temp4 = simd_or(array_u8bit__5_,array_u8bit__6_);
202        _strct_s2iclass__classify_bytes__temp5 = simd_and(array_u8bit__4_,_strct_s2iclass__classify_bytes__temp4);     
203        result = simd_andc(_strct_s2iclass__classify_bytes__temp3,_strct_s2iclass__classify_bytes__temp5);
204       
205        return result;
206}
207
208/*
209 * Binds a process to a core - Linux specifc (sched.h).
210 */
211void SetCPUAffinity();
212void SetCPUAffinity() {
213
214        printf("Setting CPU Affinity...\n");
215       
216    cpu_set_t mask;
217    unsigned int len = sizeof(mask);
218    if (sched_getaffinity(0, len, &mask) < 0) {
219        perror("sched_getaffinity");
220    }
221
222    printf("Original CPU Affinity Mask: %08lx\n", mask.__bits[0]);
223
224    //CPU_CLR(0, &mask); // (CPU 1)
225    //CPU_CLR(1, &mask); // (CPU 0)
226
227    if (sched_setaffinity(0, len, &mask) < 0) {
228       perror("sched_setaffinity");
229    }
230
231    printf("Modified CPU Affinity Mask: %08lx\n", mask.__bits[0]);
232} 
233
234int main(int argc, char * argv[]) {
235
236  if (argc < 2) {
237    printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
238          exit(-1);
239  }
240  char * filename = argv[1];
241
242  FILE *infile, *outfile;
243  infile = fopen(filename, "rb");
244  if (!infile) {
245      fprintf(stderr, "Error: cannot open %s for input.\n", filename);
246      exit(-1);
247  }
248
249  if (argc < 3) outfile = stdout;
250  else {
251    outfile = fopen(argv[2], "wb");
252    if (!outfile) {
253      fprintf(stderr, "Error: cannot open %s for writing.\n", argv[2]);
254      exit(-1);
255    }
256  }
257
258#ifdef CODE_CLOCKER
259    SetCPUAffinity();
260        char * src_filename = argv[1];
261        char * cmdline = new char[strlen(argv[0]) + strlen(argv[1]) +1 +1]; 
262        strcat(cmdline, argv[0]);
263        strcat(cmdline," ");
264        strcat(cmdline,argv[1]); 
265       
266        #define NUM_EVENTS 2
267        // PAPI_TOT_CYC 0x8000003b  Yes   No   Total cycles
268        // PAPI_L1_DCM  0x80000000  Yes   No   Level 1 data cache misses
269        // PAPI_L2_DCM  0x80000002  Yes   Yes  Level 2 data cache misses
270        // PAPI_L3_DCM  0x80000004  No    No   Level 3 data cache misses
271        // PAPI_BR_CN   0x8000002b  Yes   No   Conditional branch instructions
272        // PAPI_BR_TKN  0x8000002c  Yes   No   Conditional branch instructions taken
273        // PAPI_BR_NTK  0x8000002d  Yes   Yes  Conditional branch instructions not taken
274        // PAPI_BR_MSP  0x8000002e  Yes   No   Conditional branch instructions mispredicted
275        // PAPI_BR_PRC  0x8000002f  Yes   Yes  Conditional branch instructions correctly predicted
276       
277        int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
278        int cal_size = 1000;
279        code_clocker = new CC(Events,NUM_EVENTS,cal_size);
280        code_clocker->set_cmd(cmdline);
281#endif 
282       
283  struct stat st;
284  stat(filename, &st);
285  int filesize = st.st_size;
286  size_t bytes = filesize;
287 
288  bytes += sizeof(SIMD_type);
289 
290  // allocate a byte buffer and pad with sizeof(SIMD_type) trailing zeroes
291  unsigned char * byte_buffer = (unsigned char *)simd_new(bytes);
292     
293  // slurp a source file into a byte buffer
294  int chars_read = fread(byte_buffer, sizeof(char), filesize, infile);
295  while(chars_read > 0) {
296          chars_read = fread(byte_buffer+chars_read, sizeof(char), filesize, infile);
297  }
298 
299  // mask trailing zeroes
300  memset(byte_buffer + filesize, 0, sizeof(SIMD_type)); 
301 
302  // allocate bit stream buffer
303  int simd_packs = bytes/sizeof(SIMD_type);
304 
305  #ifdef BRANCH_REDUCTION
306    BitBlock * bit_stream_buffer = simd_new(simd_packs + 1); // pad at least an additional general width of bytes
307  #else   
308    BitBlock * bit_stream_buffer = simd_new(simd_packs);   
309  #endif
310 
311  if(bit_stream_buffer == NULL) {
312      fprintf(stderr, "Error: out of memory.\n");
313      exit(-1);   
314  }
315
316  cout << "Source bytes: " << filesize << endl;
317  cout << "Allocate bytes: " << bytes << endl;
318  cout << "SIMD packs: " << simd_packs << endl; 
319  cout << "SIMD pack bytes: " << simd_packs * sizeof(SIMD_type) << endl << endl;
320 
321  #ifdef CODE_CLOCKER
322        code_clocker->start_interval();
323  #endif       
324               
325  // convert byte packs to bit streams
326  for(int i=0,j=0;i<simd_packs;i++,j+=SIMD_REGISTER_BIT_WIDTH) {
327          bit_stream_buffer[i] = bytepack2bitblock((BytePack *)(&byte_buffer[j]));
328  }
329
330  size_t max_span_count = simd_packs * SIMD_REGISTER_BIT_WIDTH /2;     
331  size_t * starts = new size_t[max_span_count];
332  size_t * lengths = new size_t[max_span_count];
333  size_t span_count = 0;
334
335  size_t general_register_blocks;
336               
337  #ifdef BRANCH_REDUCTION
338        general_register_blocks = simd_packs * sizeof(SIMD_type);       
339        stream2runs((unsigned char *)bit_stream_buffer, general_register_blocks, starts, lengths, &span_count); // reduce bit stream butt
340  #else 
341        general_register_blocks = simd_packs * SIMD_REGISTER_BIT_WIDTH / REGISTER_BIT_WIDTH;
342        stream2runs((size_t *)bit_stream_buffer, general_register_blocks, starts, lengths, &span_count);       
343  #endif
344
345  #ifdef CODE_CLOCKER
346        code_clocker->end_interval(bytes);
347  #endif       
348
349  printf("(pos,lgth) = span_value\n");
350  for(int i =0; i<span_count; i++) {
351        printf("(%zu,%zu) = ", starts[i], lengths[i]);
352        print_chars(((char *) byte_buffer) + starts[i], lengths[i]);     
353  }     
354  printf("\n");
355               
356  delete [] starts;
357  delete [] lengths;
358 
359  if(byte_buffer != NULL) {
360          simd_delete((SIMD_type *)byte_buffer);
361  }
362 
363  if(bit_stream_buffer != NULL) {
364          simd_delete(bit_stream_buffer);
365  }
366
367  if(infile != NULL) {
368          fclose(infile);
369  }
370 
371  if(argc > 3) {
372          fclose(outfile);
373  }
374 
375  #ifdef CODE_CLOCKER
376        code_clocker->write_xml_file();
377        code_clocker->display_system_info();
378        code_clocker->display_raw_event_data();
379        delete code_clocker; 
380  #endif
381       
382  fprintf(stdout, "Done.\n");
383 
384  return(0);
385}
386
387
388
Note: See TracBrowser for help on using the repository browser.