source: branches/threaded/src/bench.c @ 74

Revision 74, 6.8 KB checked in by faltet, 4 years ago (diff)

Removed SP_BLOCKSIZE constant and use min_buffersize_parallel only.

This is simpler and new benchmarks reveal that there is not much sense
to have very small blocks like 2 KB.

Following benchmark results, the hash value for blosclz has made to not
pass 13.

Line 
1/*********************************************************************
2  Small benchmark for testing basic capabilities of Blosc.
3
4  You can select different degrees of 'randomness' in input buffer, as
5  well as external datafiles (uncomment the lines after "For data
6  coming from a file" comment).
7
8  To compile using GCC:
9
10    gcc -O3 -msse2 -o bench bench.c blosc.c blosclz.c shuffle.c
11
12  I'm collecting speeds for different machines, so the output of your
13  benchmarks and your processor specifications are welcome!
14
15  Author: Francesc Alted (faltet@pytables.org)
16
17  See LICENSES/BLOSC.txt for details about copyright and rights to use.
18**********************************************************************/
19
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#ifdef _WIN32
27  #include <time.h>
28#else
29  #include <unistd.h>
30  #include <sys/time.h>
31#endif
32#include <math.h>
33#include "blosc.h"
34
35#define MB  (1024*1024)
36
37#define NCHUNKS (100)
38#define NITER  (10)               /* Number of iterations */
39
40
41#ifdef _WIN32
42#include <windows.h>
43#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
44  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
45#else
46  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
47#endif
48
49struct timezone
50{
51  int  tz_minuteswest; /* minutes W of Greenwich */
52  int  tz_dsttime;     /* type of dst correction */
53};
54
55int gettimeofday(struct timeval *tv, struct timezone *tz)
56{
57  FILETIME ft;
58  unsigned __int64 tmpres = 0;
59  static int tzflag;
60
61  if (NULL != tv)
62  {
63    GetSystemTimeAsFileTime(&ft);
64
65    tmpres |= ft.dwHighDateTime;
66    tmpres <<= 32;
67    tmpres |= ft.dwLowDateTime;
68
69    /*converting file time to unix epoch*/
70    tmpres -= DELTA_EPOCH_IN_MICROSECS;
71    tmpres /= 10;  /*convert into microseconds*/
72    tv->tv_sec = (long)(tmpres / 1000000UL);
73    tv->tv_usec = (long)(tmpres % 1000000UL);
74  }
75
76  if (NULL != tz)
77  {
78    if (!tzflag)
79    {
80      _tzset();
81      tzflag++;
82    }
83    tz->tz_minuteswest = _timezone / 60;
84    tz->tz_dsttime = _daylight;
85  }
86
87  return 0;
88}
89#endif   /* _WIN32 */
90
91
92/* Given two timeval stamps, return the difference in seconds */
93float getseconds(struct timeval last, struct timeval current) {
94  int sec, usec;
95
96  sec = current.tv_sec - last.tv_sec;
97  usec = current.tv_usec - last.tv_usec;
98  return (float)(((double)sec + usec*1e-6)/((double)NITER*NCHUNKS)*1e6);
99}
100
101
102int get_value(int i, int rshift) {
103  int v;
104
105  v = (i<<26)^(i<<18)^(i<<11)^(i<<3)^i;
106  v &= (1 << (32-rshift)) - 1;
107  return v;
108}
109
110
111void init_buffer(void *src, int size, int rshift) {
112  unsigned int i;
113  int *_src = (int *)src;
114
115  /* To have reproducible results */
116  srand(1);
117
118  /* Initialize the original buffer */
119  for (i = 0; i < size/sizeof(int); ++i) {
120    /* Choose one below */
121    //_src[i] = 0;
122    //_src[i] = 0x01010101;
123    /* _src[i] = 0x01020304; */
124    // _src[i] = i * 1/.3;
125    // _src[i] = i;
126    //_src[i] = rand() >> rshift;
127    _src[i] = get_value(i, rshift);
128  }
129}
130
131
132int main(void) {
133  int nbytes, cbytes;
134  void *src, *srccpy;
135  void **dest[NCHUNKS], *dest2;
136  size_t i, j;
137  struct timeval last, current;
138  float tmemcpy, tshuf, tunshuf;
139  int clevel;
140  unsigned int size = 1024*1024;   /* Buffer size */
141  unsigned int elsize = 8;        /* Datatype size */
142  int rshift = 12;                /* For random data */
143  int nthreads = 4;               /* The number of threads */
144  int doshuffle = 1;              /* Shuffle? */
145  unsigned char *orig, *round;
146
147  blosc_set_nthreads(nthreads);
148  //blosc_set_min_buffersize_parallel(256*1024);
149  //blosc_set_blocksize(64*1024);
150
151  src = malloc(size);
152  srccpy = malloc(size);
153  dest2 = malloc(size);
154
155  /* Initialize buffers */
156  init_buffer(src, size, rshift);
157  memcpy(srccpy, src, size);
158  for (j = 0; j < NCHUNKS; j++) {
159    dest[j] = malloc(size);
160  }
161
162  printf("********************** Setup info *****************************\n");
163  printf("Blosc version: %s (%s)\n", BLOSC_VERSION_STRING, BLOSC_VERSION_DATE);
164  printf("Using random data with %d significant bits (out of 32)\n", 32-rshift);
165  printf("Dataset size: %d bytes\t Type size: %d bytes\n", size, elsize);
166  printf("Shuffle active?  %s\n", doshuffle ? "Yes" : "No");
167  printf("********************** Running benchmarks *********************\n");
168
169  gettimeofday(&last, NULL);
170  for (i = 0; i < NITER; i++) {
171    for (j = 0; j < NCHUNKS; j++) {
172      memcpy(dest[j], src, size);
173    }
174  }
175  gettimeofday(&current, NULL);
176  tmemcpy = getseconds(last, current);
177  printf("memcpy(write):\t\t %6.1f us, %.1f MB/s\n",
178         tmemcpy, size/(tmemcpy*MB/1e6));
179
180  gettimeofday(&last, NULL);
181  for (i = 0; i < NITER; i++) {
182    for (j = 0; j < NCHUNKS; j++) {
183      memcpy(dest2, dest[j], size);
184    }
185  }
186  gettimeofday(&current, NULL);
187  tmemcpy = getseconds(last, current);
188  printf("memcpy(read):\t\t %6.1f us, %.1f MB/s\n",
189         tmemcpy, size/(tmemcpy*MB/1e6));
190
191  for (clevel=1; clevel<10; clevel++) {
192
193    printf("Compression level: %d\n", clevel);
194    //blosc_set_nthreads(clevel);
195
196    gettimeofday(&last, NULL);
197    for (i = 0; i < NITER; i++) {
198      for (j = 0; j < NCHUNKS; j++) {
199        cbytes = blosc_compress(clevel, doshuffle, elsize, size, src, dest[j]);
200      }
201    }
202    gettimeofday(&current, NULL);
203    tshuf = getseconds(last, current);
204    printf("compression(write):\t %6.1f us, %.1f MB/s\t  ",
205           tshuf, size/(tshuf*MB/1e6));
206    printf("Final bytes: %d  ", cbytes);
207    if (cbytes > 0) {
208      printf("Compr ratio: %3.2f", size/(float)cbytes);
209    }
210    printf("\n");
211
212    /* Compressor was unable to compress.  Copy the buffer manually. */
213    if (cbytes == 0) {
214      for (j = 0; j < NCHUNKS; j++) {
215        memcpy(dest[j], src, size);
216      }
217    }
218
219    gettimeofday(&last, NULL);
220    for (i = 0; i < NITER; i++) {
221      for (j = 0; j < NCHUNKS; j++) {
222        if (cbytes == 0) {
223          memcpy(dest2, dest[j], size);
224          nbytes = size;
225        }
226        else {
227          nbytes = blosc_decompress(dest[j], dest2, size);
228        }
229      }
230    }
231    gettimeofday(&current, NULL);
232    tunshuf = getseconds(last, current);
233    printf("decompression(read):\t %6.1f us, %.1f MB/s\t  ",
234           tunshuf, nbytes/(tunshuf*MB/1e6));
235    if (nbytes < 0) {
236      printf("FAILED.  Error code: %d\n", nbytes);
237    }
238    /* printf("Orig bytes: %d\tFinal bytes: %d\n", cbytes, nbytes); */
239
240    /* Check if data has had a good roundtrip */
241    orig = (unsigned char *)srccpy;
242    round = (unsigned char *)dest2;
243    for(i = 0; i<size; ++i){
244      if (orig[i] != round[i]) {
245        printf("\nError: Original data and round-trip do not match in pos %d\n",
246               (int)i);
247        printf("Orig--> %x, round-trip--> %x\n", orig[i], round[i]);
248        goto out;
249      }
250    }
251
252    printf("OK\n");
253
254  } /* End clevel loop */
255
256 out:
257  free(src); free(srccpy); free(dest2);
258  for (i = 0; i < NCHUNKS; i++) {
259    free(dest[i]);
260  }
261
262  /* Free blosc resources */
263  blosc_free_resources();
264
265  return 0;
266}
Note: See TracBrowser for help on using the repository browser.