HyperspaceExplorer 0.7.1
|
00001 /* 00002 * File: PartitionedMultithreadedMapPrivate.h 00003 * Author: lene 00004 * 00005 * Created on April 9, 2012, 2:18 PM 00006 */ 00007 00008 #ifndef PARTITIONEDMULTITHREADEDMAPPRIVATE_H 00009 #define PARTITIONEDMULTITHREADEDMAPPRIVATE_H 00010 00011 #include <QThread> 00012 00013 namespace Multithreading { 00014 00016 namespace Private { 00017 00019 00030 template <class RandomAccessContainer, typename Function> 00031 class Kernel: public QThread { 00032 00033 public: 00034 00035 static std::vector<Kernel *> generateKernels( 00036 const RandomAccessContainer & container, RandomAccessContainer &output, Function function, unsigned tasks_per_processor 00037 ) { 00038 00039 const unsigned num_partitions = QThread::idealThreadCount()*tasks_per_processor; 00040 const unsigned elements_per_partition = container.size()/num_partitions; 00041 std::vector<Kernel*> tasks(num_partitions); 00042 00043 if (output.size() < container.size()) { 00044 output.resize(container.size()); 00045 } 00046 00047 for (unsigned index_start = 0, i = 0; index_start < container.size(); index_start += elements_per_partition, ++i) { 00048 unsigned index_end = index_start+elements_per_partition; 00049 if (index_end > container.size()) index_end = container.size(); 00050 tasks[i] = new Kernel(container, index_start, index_end, function, output); 00051 } 00052 00053 return tasks; 00054 } 00055 00056 static void startTasks(const std::vector<Kernel *> &tasks) { 00057 for (auto k: tasks) { 00058 k->start(); 00059 } 00060 } 00061 00062 static void waitForTasks(const std::vector<Kernel *> &tasks) { 00063 for (auto k: tasks) { 00064 k->wait(); 00065 } 00066 } 00067 00068 protected: 00069 00070 void run() { 00071 for (unsigned i = index_start_; i < index_end_; ++i) { 00072 output_[i] = function_(container_[i]); 00073 } 00074 } 00075 00076 private: 00077 00078 Kernel( 00079 const RandomAccessContainer & container, unsigned index_start, unsigned index_end, 00080 Function function, RandomAccessContainer & output 00081 ): 00082 container_(container), index_start_(index_start), index_end_(index_end), 00083 function_(function), output_(output) { } 00084 00085 const RandomAccessContainer & container_; 00086 unsigned index_start_; 00087 unsigned index_end_; 00088 Function function_; 00089 RandomAccessContainer & output_; 00090 00091 }; 00092 00093 } 00094 00095 } 00096 00097 #endif /* PARTITIONEDMULTITHREADEDMAPPRIVATE_H */