| 48 | class OutputIterator, |
| 49 | class Compare> |
| 50 | inline OutputIterator merge(InputIterator1 first1, |
| 51 | InputIterator1 last1, |
| 52 | InputIterator2 first2, |
| 53 | InputIterator2 last2, |
| 54 | OutputIterator result, |
| 55 | Compare comp, |
| 56 | command_queue &queue = system::default_queue()) |
| 57 | { |
| 58 | BOOST_STATIC_ASSERT(is_device_iterator<InputIterator1>::value); |
| 59 | BOOST_STATIC_ASSERT(is_device_iterator<InputIterator2>::value); |
| 60 | BOOST_STATIC_ASSERT(is_device_iterator<OutputIterator>::value); |
| 61 | typedef typename std::iterator_traits<InputIterator1>::value_type input1_type; |
| 62 | typedef typename std::iterator_traits<InputIterator2>::value_type input2_type; |
| 63 | typedef typename std::iterator_traits<OutputIterator>::value_type output_type; |
| 64 | |
| 65 | const device &device = queue.get_device(); |
| 66 | |
| 67 | std::string cache_key = |
| 68 | std::string("__boost_merge_") + type_name<input1_type>() + "_" |
| 69 | + type_name<input2_type>() + "_" + type_name<output_type>(); |
| 70 | boost::shared_ptr<detail::parameter_cache> parameters = |
| 71 | detail::parameter_cache::get_global_cache(device); |
| 72 | |
| 73 | // default serial merge threshold depends on device type |
| 74 | size_t default_serial_merge_threshold = 32768; |
| 75 | if(device.type() & device::gpu) { |
| 76 | default_serial_merge_threshold = 2048; |
| 77 | } |
| 78 | |
| 79 | // loading serial merge threshold parameter |
| 80 | const size_t serial_merge_threshold = |
| 81 | parameters->get(cache_key, "serial_merge_threshold", |
| 82 | static_cast<uint_>(default_serial_merge_threshold)); |
| 83 | |
| 84 | // choosing merge algorithm |
| 85 | const size_t total_count = |
| 86 | detail::iterator_range_size(first1, last1) |
| 87 | + detail::iterator_range_size(first2, last2); |
| 88 | // for small inputs serial merge turns out to outperform |
| 89 | // merge with merge path algorithm |
| 90 | if(total_count <= serial_merge_threshold){ |
| 91 | return detail::serial_merge(first1, last1, first2, last2, result, comp, queue); |
| 92 | } |
| 93 | return detail::merge_with_merge_path(first1, last1, first2, last2, result, comp, queue); |
| 94 | } |
| 95 | |
| 96 | /// \overload |
| 97 | template<class InputIterator1, class InputIterator2, class OutputIterator> |