From 7efe72ebb3dcb0b9239a7f0d375f2bc9ebdaa7b4 Mon Sep 17 00:00:00 2001 From: Bo Wang Date: Tue, 22 Apr 2014 21:57:39 -0400 Subject: [PATCH] chapter 2 code --- ch2/Makefile | 19 +++++++++++++ ch2/accumulate.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 ch2/Makefile create mode 100644 ch2/accumulate.cpp diff --git a/ch2/Makefile b/ch2/Makefile new file mode 100644 index 0000000..8d7d7a8 --- /dev/null +++ b/ch2/Makefile @@ -0,0 +1,19 @@ +CPP = g++ +CPPFLAGS = -g -std=c++0x +OFLAG = -o +.SUFFIXES : .o .cpp .c +.cpp.o : + $(CPP) $(CPPFLAGS) -c $< +.c.o : + $(CPP) $(CPPFLAGS) -c $< + +PROGS = accumulate + +all: $(PROGS) + +accumulate: accumulate.o + $(CPP) $(OFLAG) accumulate accumulate.o -lpthread + +clean: + rm -f ${PROGS} *.o + diff --git a/ch2/accumulate.cpp b/ch2/accumulate.cpp new file mode 100644 index 0000000..372f1fe --- /dev/null +++ b/ch2/accumulate.cpp @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include // std::accumulate + +template +struct accumulate_block +{ + void operator()(Iterator first, Iterator last, T& result) + { + result = std::accumulate(first,last,result); + } +}; + +template +T parallel_accumulate(Iterator first, Iterator last, T init) +{ + unsigned long const length = std::distance(first,last); + + if (!length) return init; + + unsigned long const min_per_thread = 25; + unsigned long const max_threads = + (length+min_per_thread-1)/min_per_thread; + + unsigned long const hardware_threads = + std::thread::hardware_concurrency(); + + unsigned long const num_threads = + std::min(hardware_threads != 0 ? hardware_threads:2, max_threads); + + unsigned long const block_size = length / num_threads; + + std::vector results(num_threads); + std::vector threads(num_threads-1); + + Iterator block_start = first; + for (unsigned long i = 0; i < (num_threads-1); ++i) + { + Iterator block_end = block_start; + std::advance(block_end,block_size); + threads[i] = std::thread( + accumulate_block(), + block_start,block_end,std::ref(results[i])); + block_start = block_end; + } + accumulate_block::iterator,int>()( + block_start,last,results[num_threads-1]); + + std::for_each(threads.begin(),threads.end(), + std::mem_fn(&std::thread::join)); + + return std::accumulate(results.begin(),results.end(),init); +} + +int main() +{ + std::vector numbers(50); + for (int i = 0; i < 50; ++i) { + numbers[i] = i; + } + int result = parallel_accumulate::iterator,int> + (numbers.begin(),numbers.end(),0); + + std::cout << "result: " << result << std::endl; +} +