JayBeams  0.1
Another project to have fun coding.
bm_copy_buffer.cpp
Go to the documentation of this file.
5 
6 #include <boost/compute/algorithm/copy.hpp>
7 #include <boost/compute/command_queue.hpp>
8 #include <boost/compute/container/vector.hpp>
9 #include <cstdint>
10 #include <iostream>
11 #include <stdexcept>
12 #include <string>
13 #include <unistd.h>
14 
15 namespace {
17 
18 /// Create all the testcases
20 
21 } // anonymous namespace
22 
23 int main(int argc, char* argv[]) {
24  // Simply call the generic microbenchmark for a group of testcases
25  // ...
26  auto testcases = create_test_cases();
27  return jb::testing::microbenchmark_group_main<config>(argc, argv, testcases);
28 }
29 
30 namespace {
31 // By default use a single page, at least a typical page size
32 int get_page_size() {
33  return static_cast<int>(sysconf(_SC_PAGESIZE));
34 }
35 
36 int default_size() {
37  int pagesize = get_page_size();
38  return pagesize;
39 }
40 
41 template <bool upload>
42 class fixture {
43 public:
44  fixture(
45  boost::compute::context& context, boost::compute::command_queue& q,
46  bool aligned)
47  : fixture(default_size(), context, q, aligned) {
48  }
49  fixture(
50  int size, boost::compute::context& context,
51  boost::compute::command_queue& q, bool aligned)
52  : dev(size / sizeof(int), context)
53  , host((size + get_page_size()) / sizeof(int))
54  , queue(q)
55  , start(host.begin())
56  , end(host.begin() + size / sizeof(int)) {
57  int pagesize = get_page_size();
58  std::intptr_t ptr =
59  reinterpret_cast<std::intptr_t>(boost::addressof(*start));
60  if (not aligned) {
61  if (ptr % pagesize == 0) {
62  // simply increment the ptr to get an unaligned buffer
63  ++start;
64  ++end;
65  }
66  return;
67  }
68  while (ptr % pagesize != 0 and ++start != host.end() and
69  ++end != host.end()) {
70  ptr = reinterpret_cast<std::intptr_t>(boost::addressof(*start));
71  }
72  if (ptr % pagesize != 0) {
73  throw std::runtime_error("Could not align buffer");
74  }
75  }
76 
77  int run() {
78  boost::compute::copy(start, end, dev.begin(), queue);
79  queue.finish();
80  return static_cast<int>(dev.size());
81  }
82 
83 private:
84  boost::compute::vector<int> dev;
85  std::vector<int> host;
86  boost::compute::command_queue queue;
87  std::vector<int>::iterator start;
88  std::vector<int>::iterator end;
89 };
90 
91 /// Implement the download case
92 template <>
93 int fixture<false>::run() {
94  boost::compute::copy(dev.begin(), dev.end(), start, queue);
95  queue.finish();
96  return static_cast<int>(dev.size());
97 }
98 
99 template <bool upload, bool aligned>
100 std::function<void(config const&)> test_case() {
101  return [](config const& cfg) {
102  boost::compute::device device = jb::opencl::device_selector(cfg.opencl());
103  boost::compute::context context(device);
104  boost::compute::command_queue queue(context, device);
106  benchmark bm(cfg.microbenchmark());
107 
108  auto r = bm.run(context, queue, aligned);
109  bm.typical_output(r);
110  };
111 }
112 
113 jb::testing::microbenchmark_group<config> create_test_cases() {
115  {"upload:aligned", test_case<true, true>()},
116  {"upload:misaligned", test_case<true, false>()},
117  {"download:aligned", test_case<false, true>()},
118  {"download:misaligned", test_case<false, false>()},
119  };
120 }
121 
122 } // anonymous namespace
boost::compute::device device_selector(config const &cfg)
Select an OpenCL device matching the current configuration.
The configuration shared by all OpenCL microbenchmarks.
results run(Args &&... args)
Run the microbenchmaark.
std::map< std::string, std::function< void(config const &cfg)> > microbenchmark_group
Define a representation for a group of microbenchmarks.
Run a micro-benchmark on a given class.
int main(int argc, char *argv[])