-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsum.cpp
More file actions
135 lines (99 loc) · 3.93 KB
/
Copy pathsum.cpp
File metadata and controls
135 lines (99 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// sum.cpp
// ThreadingExample
//
// Created by Sarah Westcott on 12/16/24.
// Copyright (c) 2024 Schloss Lab. All rights reserved.
//
#include "sum.h"
/******************************************************************************/
//custom data structure for threads to use.
// This is passed by void pointer so it can be any data type
// that can be passed using a single void pointer (LPVOID).
struct sumData {
// variable containing portion of the data to sum
vector<int> partialData;
// variable containing subtotal to return to main process
int partialSum;
// sumData default constructor
sumData() {
partialSum = 0;
}
// sumData custom constructor
sumData(const vector<int>& d) {
partialData = d;
partialSum = 0;
}
// sumData deconstructor
~sumData() = default;
};
/******************************************************************************/
// class constructor
Sum::Sum(const int proc) {
processors = proc;
}
/******************************************************************************/
// class function for calculating the sum of data
int Sum::accumulate(const Rcpp::IntegerVector& data) {
int result = 0;
// convert data
vector<int> my_data = Rcpp::as<std::vector<int> >(data);
result = createProcesses(my_data);
return result;
}
/******************************************************************************/
// Important notes:
// 1. non class function that will be run in parallel
// - this is the where the work is done
// 2. must be defined (appear in the file) before function calling it
// 3. must return void, all inputs and results are passed in the sumData struct
// 4. can call other globally defined functions, and use any classes
// 5. All functions called / data structures used must be thread safe
// - https://en.wikipedia.org/wiki/Thread_safety
// sumData - partialSum, partialData
void driverAccumulate(sumData* params){
// loop over partialData adding to partialSum
for(int i = 0; i < params->partialData.size(); i++) {
RcppThread::checkUserInterrupt();
params->partialSum += params->partialData[i];
}
}
/******************************************************************************/
// class function for dividing work, creating and destroying threads
int Sum::createProcesses(const vector<int>& data) {
// use divideWork function (numItems, numProcessors)
Utils util;
vector<pieceOfWork> startEnds = util.divideWork(data.size(), processors);
vector<RcppThread::Thread*> workerThreads;
vector<sumData*> threadData;
//Launch worker threads
for (int i = 0; i < processors-1; i++) {
// create sumData* containing this thread's piece of work
sumData* threadSum = new sumData(slicing(data, startEnds[i+1].start,
startEnds[i+1].end));
// save sumData* for later access
threadData.emplace_back(threadSum);
// create thread and save for join
workerThreads.push_back(new RcppThread::Thread(driverAccumulate,
threadSum));
}
// create sumData* containing main thread's piece of work
sumData* firstSum = new sumData(slicing(data, startEnds[0].start,
startEnds[0].end));
// run worker function with main thread
driverAccumulate(firstSum);
// collect main thread's results
int total = firstSum->partialSum;
// delete main thread's sumData*
delete firstSum;
for (int i = 0; i < processors-1; i++) {
// join threads
workerThreads[i]->join();
// collect worker thread's results
total+=threadData[i]->partialSum;
// delete worker thread's sumData* and delete thread
delete threadData[i], workerThreads[i];
}
return total;
}
/******************************************************************************/