Advertisement
Guest User

Untitled

a guest
Dec 26th, 2024
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.01 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <inttypes.h>
  6. #include <sys/time.h>
  7. #include <sys/uio.h>
  8. #include <sys/mman.h>
  9. #include <sys/stat.h>
  10. #include <sys/sysmacros.h>
  11. #include <dirent.h>
  12. #include <string.h>
  13. #include <pthread.h>
  14. #include <errno.h>
  15. #include <numa.h>
  16.  
  17. #define RWF_UNCACHED 0x80
  18.  
  19. static int random_io = 0;
  20.  
  21. static unsigned long long mtime_since(const struct timeval *s,
  22. const struct timeval *e)
  23. {
  24. long long sec, usec;
  25.  
  26. sec = e->tv_sec - s->tv_sec;
  27. usec = (e->tv_usec - s->tv_usec);
  28. if (sec > 0 && usec < 0) {
  29. sec--;
  30. usec += 1000000;
  31. }
  32.  
  33. sec *= 1000;
  34. usec /= 1000;
  35. return sec + usec;
  36. }
  37.  
  38. static unsigned long long mtime_since_now(struct timeval *tv)
  39. {
  40. struct timeval end;
  41.  
  42. gettimeofday(&end, NULL);
  43. return mtime_since(tv, &end);
  44. }
  45.  
  46. struct thread_data {
  47. pthread_t thread;
  48. pthread_barrier_t barrier;
  49. int fd;
  50. volatile int done;
  51. int rwf_flags;
  52. int bs;
  53. int reading;
  54. void *buf;
  55. unsigned long max_blocks;
  56. unsigned long bytes;
  57. };
  58.  
  59. static off_t next_off(struct thread_data *d, off_t last_off, int bytes)
  60. {
  61. if (random_io) {
  62. long off = lrand48();
  63. long block = off % d->max_blocks;
  64. return block * d->bs;
  65. }
  66. return last_off + bytes;
  67. }
  68.  
  69. static void *thread_fn(void *__data)
  70. {
  71. struct thread_data *d = __data;
  72. struct iovec iov = { .iov_len = d->bs };
  73. const char *msg = d->reading ? "preadv2" : "pwritev2";
  74. off_t offset = 0;
  75. struct stat sb;
  76.  
  77. if (fstat(d->fd, &sb) < 0) {
  78. perror("fstat");
  79. goto done;
  80. }
  81. if (random_io)
  82. d->max_blocks = sb.st_size / d->bs;
  83.  
  84. if (posix_memalign(&d->buf, 4096, d->bs))
  85. goto done;
  86. iov.iov_base = d->buf;
  87.  
  88. pthread_barrier_wait(&d->barrier);
  89.  
  90. for (;;) {
  91. int ret;
  92.  
  93. if (d->reading)
  94. ret = preadv2(d->fd, &iov, 1, offset, d->rwf_flags);
  95. else
  96. ret = pwritev2(d->fd, &iov, 1, offset, d->rwf_flags);
  97. if (ret < 0) {
  98. perror(msg);
  99. break;
  100. } else if (!ret) {
  101. break;
  102. }
  103.  
  104. d->bytes += ret;
  105. offset = next_off(d, offset, ret);
  106. }
  107. done:
  108. d->done = 1;
  109. return NULL;
  110. }
  111.  
  112. int main(int argc, char *argv[])
  113. {
  114. struct timeval tv, start;
  115. unsigned int bs;
  116. unsigned long last_bytes = 0, bytes = 0;
  117. struct thread_data *td;
  118. int rwf_flags = 0;
  119. int reading = 1;
  120. int nr, i;
  121.  
  122. if (argc < 5) {
  123. printf("%s: bs uncached reading <files>\n", argv[0]);
  124. return 1;
  125. }
  126.  
  127. bs = atoi(argv[1]);
  128. if (!!atoi(argv[2]))
  129. rwf_flags |= RWF_UNCACHED;
  130. reading = !!atoi(argv[3]);
  131.  
  132. nr = argc - 4;
  133. if (!nr) {
  134. fprintf(stderr, "Need files\n");
  135. return 1;
  136. }
  137.  
  138. if (!reading)
  139. random_io = 0;
  140.  
  141. td = calloc(nr, sizeof(struct thread_data));
  142.  
  143. for (i = 0; i < nr; i++) {
  144. int flags;
  145.  
  146. if (reading)
  147. flags = O_RDONLY;
  148. else
  149. flags = O_WRONLY;
  150. again:
  151. td[i].fd = open(argv[4 + i], flags, 0644);
  152. if (td[i].fd < 0) {
  153. if (!reading && errno == ENOENT) {
  154. flags |= O_CREAT;
  155. goto again;
  156. }
  157. perror("open");
  158. return 1;
  159. }
  160. posix_fadvise(td[i].fd, 0, (off_t) -1, POSIX_FADV_RANDOM);
  161. posix_fadvise(td[i].fd, 0, (off_t) -1, POSIX_FADV_DONTNEED);
  162. td[i].rwf_flags = rwf_flags;
  163. td[i].bs = bs;
  164. td[i].reading = reading;
  165. }
  166.  
  167. printf("Starting %d threads\n", nr);
  168. for (i = 0; i < nr; i++) {
  169. pthread_barrier_init(&td[i].barrier, NULL, 2);
  170. pthread_create(&td[i].thread, NULL, thread_fn, &td[i]);
  171. pthread_barrier_wait(&td[i].barrier);
  172. }
  173.  
  174. printf("%sing bs %u, uncached %d\n", reading ? "read" : "writ", bs, (rwf_flags & RWF_UNCACHED) != 0);
  175. gettimeofday(&tv, NULL);
  176. start = tv;
  177. do {
  178. unsigned long mb, msec;
  179. int done = 0;
  180.  
  181. usleep(100000);
  182. msec = mtime_since_now(&tv);
  183. bytes = 0;
  184. for (i = 0; i < nr; i++) {
  185. bytes += td[i].bytes;
  186. done += td[i].done;
  187. }
  188. if (msec < 1000 && (done != nr))
  189. continue;
  190.  
  191. mb = (bytes - last_bytes) >> 10;
  192. last_bytes = bytes;
  193. gettimeofday(&tv, NULL);
  194. printf("%3llds: %luMB/sec, MB=%lu\n", mtime_since_now(&start) / 1000, mb / msec, (bytes / msec) >> 10);
  195. if (done == nr)
  196. break;
  197. } while (1);
  198.  
  199. return 0;
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement