\(\newcommand{\W}[1]{ \; #1 \; }\) \(\newcommand{\R}[1]{ {\rm #1} }\) \(\newcommand{\B}[1]{ {\bf #1} }\) \(\newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} }\) \(\newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} }\) \(\newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} }\) \(\newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }\)
harmonic_setup¶
View page sourceSet Up Multi-threading Sum of 1/i¶
Syntax¶
ok =
harmonic_setup
( num_sum )Purpose¶
This routine does the setup for splitting the summation that defines the harmonic series
\[1 + 1/2 + 1/3 + ... + 1/n\]
into separate parts for each thread.
Thread¶
It is assumed that this function is called by thread zero, and all the other threads are blocked (waiting).
num_sum¶
The argument num_sum has prototype
size_t
num_sum
It specifies the value of \(n\) in the summation.
Source¶
namespace {
bool harmonic_setup(size_t num_sum)
{ // sum = 1/num_sum + 1/(num_sum-1) + ... + 1
size_t num_threads = std::max(num_threads_, size_t(1));
bool ok = num_threads == thread_alloc::num_threads();
ok &= thread_alloc::thread_num() == 0;
ok &= num_sum >= num_threads;
//
for(size_t thread_num = 0; thread_num < num_threads; thread_num++)
{ // allocate separate memory for this thread to avoid false sharing
size_t min_bytes(sizeof(work_one_t)), cap_bytes;
void* v_ptr = thread_alloc::get_memory(min_bytes, cap_bytes);
work_all_[thread_num] = static_cast<work_one_t*>(v_ptr);
//
// in case this thread's worker does not get called
work_all_[thread_num]->ok = false;
// parameters that define the work for this and previous thread
if( thread_num == 0 )
work_all_[0]->start = 1;
else
{ size_t index = (num_sum * thread_num) / num_threads;
work_all_[thread_num-1]->stop = index;
work_all_[thread_num]->start = index;
}
}
work_all_[num_threads-1]->stop = num_sum + 1;
return ok;
}
}