Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <stdint.h>
- #include <sys/mman.h>
- #include <omp.h>
- #define KB (1024)
- #define MB (1024*KB)
- #define GB (1024ul*MB)
- typedef struct {
- void * data;
- uint64_t len;
- } vec_t;
- static inline vec_t vec_alloc(uint64_t size, uint64_t prot, uint64_t flags) {
- return (vec_t){mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANONYMOUS | flags, 0, 0), size};
- }
- static inline vec_t vec_allocrwp(uint64_t size) {
- return vec_alloc(size, PROT_WRITE | PROT_READ, MAP_POPULATE);
- }
- static inline void vec_dealloc(vec_t v) {
- munmap(v.data, v.len);
- }
- typedef uint32_t v4_t __attribute__ ((__vector_size__ (16)));
- static inline uint32_t vhsumm(v4_t v) {
- return v[0] + v[1] + v[2] + v[3];
- }
- static inline void * vend(vec_t v) {
- return v.data + v.len;
- }
- static inline void * vbegin(vec_t v) {
- return v.data;
- }
- static inline uint32_t vmhsumm(vec_t vec) {
- v4_t * it = vbegin(vec), * end = vend(vec);
- v4_t summ = {0};
- do {
- summ += *it++;
- } while(it != end);
- return vhsumm(summ);
- }
- #define vmhsumm(m) vmhsumm((vec_t){m, sizeof(m)})
- static inline uint32_t vsumm(vec_t vec) {
- v4_t * it = vbegin(vec), * end = vend(vec);
- v4_t summ[4] = {{0}};
- do {
- summ[0] += *it++;
- summ[1] += *it++;
- summ[2] += *it++;
- summ[3] += *it++;
- } while(it != end);
- return vmhsumm(summ);
- }
- uint32_t summ(vec_t vec) {
- uint32_t * it = vbegin(vec), * end = vend(vec);
- uint32_t sum = 0;
- do {
- sum+= *it;
- } while(++it != end);
- return sum;
- }
- static inline vec_t mvec_init(vec_t vec) {
- uint32_t * it = vbegin(vec), t = 0, len = vec.len/4;
- do {
- *it++ = t++;
- } while(t != len);
- return vec;
- }
- static vec_t bench_f(vec_t vec, typeof(vsumm) f, uint64_t pass) {
- uint32_t res = 0; uint64_t i = 0;
- double start = omp_get_wtime();
- do {
- res = f(vec);
- } while(++i != pass);
- double time = omp_get_wtime() - start;
- fprintf(stderr, "summ: %u, perf: %lfGB/s, pass_time: %lfs\n", res, ((vec.len * pass)/time)/GB, time/pass);
- return vec;
- }
- static inline void bench_vsumm(uint64_t pass_size, uint64_t total_size) {
- vec_dealloc(bench_f(mvec_init(vec_allocrwp(pass_size)), vsumm, total_size/pass_size));
- }
- // static inline void bench_summ(uint64_t pass_size, uint64_t total_size) {
- // vec_dealloc(bench_f(mvec_init(vec_allocrwp(pass_size)), summ, total_size/pass_size));
- // }
- int main(void) {
- // bench_summ((2 * KB), (32 * GB));
- bench_vsumm((2 * KB), (32 * GB));
- // bench_summ((2 * MB), (16 * GB));
- bench_vsumm((2 * MB), (16 * GB));
- // bench_summ(GB, (8 * GB));
- bench_vsumm(GB, (8 * GB));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment