tlds
Transactional Operations for Linked Data Structures
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
policies.hpp
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2011
3  * University of Rochester Department of Computer Science
4  * and
5  * Lehigh University Department of Computer Science and Engineering
6  *
7  * License: Modified BSD
8  * Please see the file LICENSE.RSTM for licensing information
9  */
10 
11 #ifndef POLICIES_HPP__
12 #define POLICIES_HPP__
13 
14 #include <stm/config.h>
15 #ifdef STM_CC_SUN
16 #include <stdio.h>
17 #else
18 #include <cstdio>
19 #endif
20 
21 #include <inttypes.h>
22 #include <common/platform.hpp>
23 #include <stm/metadata.hpp>
24 #include <stm/txthread.hpp>
25 #include <stm/lib_globals.hpp>
26 
27 namespace stm
28 {
29  /**
30  * These define the different adaptivity policies. A policy is a name, the
31  * starting mode, and some information about how/when to adapt.
32  */
33  struct pol_t
34  {
35  /*** the name of this policy */
36  const char* name;
37 
38  /*** name of the mode that we start in */
39  int startmode;
40 
41  /*** thresholds for adapting due to aborts and waiting */
44 
45  /*** does the policy use profiles? */
46  bool isDynamic;
47 
48  /*** does the policy require a qtable? */
49  bool isCBR;
50 
51  /*** does the policy have commit-based reprofiling? */
53 
54  /*** the decision policy function pointer */
55  uint32_t (*TM_FASTCALL decider) ();
56 
57  /*** simple ctor, because a NULL name is a bad thing */
58  pol_t() : name(""){ }
59  };
60 
61  /**
62  * This describes the state of the selected policy. This should be a
63  * singleton, but we don't bother. There will be one of these, which we
64  * can use to tell what the current policy is that libstm is using.
65  */
66  struct behavior_t
67  {
68  // name of current policy
69  uint32_t POL_ID;
70 
71  // name of current algorithm
72  volatile uint32_t ALG_ID;
73 
74  // name of alg before the last profile was collected
75  uint32_t PREPROFILE_ALG;
76 
77  // did we make a decision due to aborting?
79 
80  // so we can backoff on our thresholds when we have repeat
81  // algorithim selections
84  };
85 
86  /**
87  * Data type for holding the dynamic transaction profiles that we collect.
88  * This is pretty sloppy for now, and the 'dump' command is really not
89  * going to be important once we get out of the debug phase. We may also
90  * determine that we need more information than we currently have.
91  */
92  struct dynprof_t
93  {
94  int read_ro; // calls to read_ro
95  int read_rw_nonraw; // read_rw calls that are not raw
96  int read_rw_raw; // read_rw calls that are raw
97  int write_nonwaw; // write calls that are not waw
98  int write_waw; // write calls that are waw
99  int pad; // to put the 64-bit val on a 2-byte boundary
100  uint64_t txn_time; // txn time
101  uint64_t timecounter; // total time in transactions
102 
103  // to be clear: txn_time is either the average time for all
104  // transactions, or the max time of any transaction. timecounter is
105  // the sum of all time in transactions. timecounter only is useful for
106  // profileapp, but it is very important if we want to compute nontx/tx
107  // ratio when txn_time is a max value
108 
109  /**
110  * simple ctor to prevent compiler warnings
111  */
114  write_waw(0), pad(0), txn_time(0), timecounter(0)
115  {
116  }
117 
118  /**
119  * Operator for copying profiles
120  */
121  dynprof_t& operator=(const dynprof_t* profile)
122  {
123  if (this != profile) {
124  read_ro = profile->read_ro;
125  read_rw_nonraw = profile->read_rw_nonraw;
126  read_rw_raw = profile->read_rw_raw;
127  write_nonwaw = profile->write_nonwaw;
128  write_waw = profile->write_waw;
129  txn_time = profile->txn_time;
130  }
131  return *this;
132  }
133 
134  /**
135  * Print a dynprof_t
136  */
137  void dump()
138  {
139  printf("Profile: read_ro=%d, read_rw_nonraw=%d, read_rw_raw=%d, "
140  "write_nonwaw=%d, write_waw=%d, txn_time=%llu\n",
142  write_waw, (unsigned long long)txn_time);
143  }
144 
145  /**
146  * Clear a dynprof_t
147  */
148  void clear()
149  {
151  write_nonwaw = write_waw = 0;
152  txn_time = timecounter = 0;
153  }
154 
155  /**
156  * If we have lots of profiles, compute their average value for each
157  * field
158  */
159  static void doavg(dynprof_t& dest, dynprof_t* list, int num)
160  {
161  // zero the important fields
162  dest.clear();
163 
164  // accumulate sums into dest
165  for (int i = 0; i < num; ++i) {
166  dest.read_ro += list[i].read_ro;
167  dest.read_rw_nonraw += list[i].read_rw_nonraw;
168  dest.read_rw_raw += list[i].read_rw_raw;
169  dest.write_nonwaw += list[i].write_nonwaw;
170  dest.write_waw += list[i].write_waw;
171  dest.txn_time += list[i].txn_time;
172  }
173 
174  // compute averages
175  dest.read_ro /= num;
176  dest.read_rw_nonraw /= num;
177  dest.read_rw_raw /= num;
178  dest.write_nonwaw /= num;
179  dest.write_waw /= num;
180  dest.txn_time /= num;
181  }
182  };
183 
184  /**
185  * This is for storing our CBR-style qtable
186  *
187  * The qtable tells us for a particular workload characteristic, what
188  * algorithm did best at each thread count.
189  */
190  struct qtable_t
191  {
192  /**
193  * Selection Fields
194  *
195  * NB: These fields are for choosing the output: For a given behavior,
196  * choose the algorithm that maximizes throughput.
197  */
198 
199  /*** The name of the STM algorithm that produced this result */
200  int alg_name;
201 
202  /**
203  * Transaction Behavior Summary
204  *
205  * NB: The profile holds a characterization of the transactions of the
206  * workload, with regard to reads and writes, and the time spent
207  * on a transaction. Depending on which variant of ProfileApp was
208  * used to create this profile, it will either hold average values,
209  * or max values.
210  *
211  * NB: We assume that a summary of transactions in the single-thread
212  * execution is appropriate for the behavior of transactions in a
213  * multithreaded execution.
214  */
216 
217  /**
218  * Workload Behavior Summary
219  */
220 
221  /**
222  * The ratio of transactional work to nontransactional work
223  */
225 
226  /**
227  * The percentage of transactions that are Read-Only
228  */
229  int pct_ro;
230 
231  /*** The thread count at which this result was measured */
232  int thr;
233 
234  /*** really simple ctor */
235  qtable_t() : pct_ro(0) { }
236  };
237 
238  /*** Used in txthread to initialize the policy subsystem */
239  void pol_init(const char* mode);
240 
241  /**
242  * Just like stm_name_map, we sometimes need to turn a policy name into its
243  * corresponding enum value
244  */
245  int pol_name_map(const char* phasename);
246 
247  /**
248  * The POLS enum lists every adaptive policy we have
249  */
250  enum POLS {
251  // this is a "no adaptivity" policy
253  // Testing policy, to make sure profiles are working
255  // the state-machine policies
256  E, ER, R, X,
257  // CBR without dynamic profiling
259  // CBR with dynamic profiling
269  // max value... this always goes last
271  };
272 
273  /**
274  * These globals are used by our adaptivity policies
275  */
276  extern pol_t pols[POL_MAX]; // describe all policies
277  extern MiniVector<qtable_t>* qtbl[MAX_THREADS+1]; // hold the CBR data
278  extern behavior_t curr_policy; // the current STM alg
279 
280  /**
281  * Helper function. This is a terrible thing, and one we must get rid of,
282  * especially since we are calling it far more often than we should!
283  */
284  TM_INLINE
285  inline unsigned long long get_nontxtime()
286  {
287  // extimate the global nontx time per transaction
288  uint32_t commits = 1;
289  unsigned long long nontxn_time = 0;
290  for (unsigned z = 0; z < threadcount.val; z++){
291  nontxn_time += threads[z]->total_nontxn_time;
292  commits += threads[z]->num_commits;
293  commits += threads[z]->num_ro;
294  }
295  commits += !commits; // if commits is 0, make it 1, without control flow
296  unsigned long long ans = 1 + (nontxn_time / commits);
297  return ans;
298  }
299 
300  /*** used in the policies impementations to register policies */
301  void init_adapt_pol(uint32_t PolicyID, int32_t startmode,
302  int32_t abortThresh, int32_t waitThresh,
303  bool isDynamic, bool isCBR,
304  bool isCommitProfile, uint32_t (*decider)() TM_FASTCALL,
305  const char* name);
306 
307 } // namespace stm
308 
309 #endif // POLICIES_HPP__
Definition: policies.hpp:262
Definition: policies.hpp:267
int startmode
Definition: policies.hpp:39
TxThread * threads[MAX_THREADS]
Definition: txthread.cpp:56
void clear()
Definition: policies.hpp:148
bool abort_switch
Definition: policies.hpp:78
Definition: stm_fraser.c:61
Definition: policies.hpp:261
Definition: policies.hpp:260
Definition: policies.hpp:33
dynprof_t()
Definition: policies.hpp:112
bool isCBR
Definition: policies.hpp:49
int read_ro
Definition: policies.hpp:94
int abortThresh
Definition: policies.hpp:82
Definition: policies.hpp:267
Definition: policies.hpp:256
Definition: policies.hpp:66
static void doavg(dynprof_t &dest, dynprof_t *list, int num)
Definition: policies.hpp:159
dynprof_t & operator=(const dynprof_t *profile)
Definition: policies.hpp:121
Definition: policies.hpp:265
Definition: policies.hpp:260
dynprof_t p
Definition: policies.hpp:215
pol_t pols[POL_MAX]
Definition: policies.cpp:107
Definition: policies.hpp:261
Definition: policies.hpp:252
qtable_t()
Definition: policies.hpp:235
Definition: policies.hpp:92
void dump()
Definition: policies.hpp:137
volatile uintptr_t val
Definition: metadata.hpp:117
Definition: policies.hpp:263
int txn_ratio
Definition: policies.hpp:224
uint64_t txn_time
Definition: policies.hpp:100
pol_t()
Definition: policies.hpp:58
int thr
Definition: policies.hpp:232
Definition: policies.hpp:265
uint32_t POL_ID
Definition: policies.hpp:69
Definition: policies.hpp:263
Definition: policies.hpp:262
int write_waw
Definition: policies.hpp:98
Definition: policies.hpp:266
pad_word_t threadcount
Definition: WBMMPolicy.hpp:35
Definition: policies.hpp:261
Definition: policies.hpp:190
uint32_t num_ro
Definition: txthread.hpp:56
MiniVector< qtable_t > * qtbl[MAX_THREADS+1]
Definition: policies.cpp:111
Definition: policies.hpp:262
Definition: policies.hpp:268
Definition: policies.hpp:270
Definition: policies.hpp:258
Definition: policies.hpp:260
Definition: policies.hpp:256
bool isCommitProfile
Definition: policies.hpp:52
Definition: policies.hpp:263
#define TM_INLINE
Definition: platform.hpp:77
POLS
Definition: policies.hpp:250
Definition: policies.hpp:256
Definition: policies.hpp:262
behavior_t curr_policy
Definition: policies.cpp:108
Definition: policies.hpp:266
Definition: policies.hpp:254
Definition: policies.hpp:263
Definition: policies.hpp:264
int pad
Definition: policies.hpp:99
uint64_t total_nontxn_time
Definition: txthread.hpp:93
uint32_t num_commits
Definition: txthread.hpp:53
bool isDynamic
Definition: policies.hpp:46
volatile uint32_t ALG_ID
Definition: policies.hpp:72
Definition: policies.hpp:264
int waitThresh
Definition: policies.hpp:83
int pol_name_map(const char *phasename)
Definition: policies.cpp:114
Definition: policies.hpp:260
int waitThresh
Definition: policies.hpp:43
Definition: policies.hpp:264
static const unsigned MAX_THREADS
Definition: metadata.hpp:33
Definition: policies.hpp:267
Definition: list.h:93
int alg_name
Definition: policies.hpp:200
uint32_t PREPROFILE_ALG
Definition: policies.hpp:75
uint32_t(* TM_FASTCALL)()
Definition: policies.hpp:55
int write_nonwaw
Definition: policies.hpp:97
Definition: policies.hpp:261
TM_INLINE unsigned long long get_nontxtime()
Definition: policies.hpp:285
Definition: policies.hpp:266
void init_adapt_pol(uint32_t PolicyID, int32_t startmode, int32_t abortThresh, int32_t waitThresh, bool isDynamic, bool isCBR, bool isCommitProfile, uint32_t TM_FASTCALL(*decider)(), const char *name)
Definition: policies.cpp:130
uint64_t timecounter
Definition: policies.hpp:101
void pol_init(const char *mode)
Definition: policies.cpp:148
int abortThresh
Definition: policies.hpp:42
int read_rw_nonraw
Definition: policies.hpp:95
Definition: policies.hpp:264
int pct_ro
Definition: policies.hpp:229
int read_rw_raw
Definition: policies.hpp:96
Definition: policies.hpp:265
Definition: policies.hpp:256
const char * name
Definition: policies.hpp:36
#define TM_FASTCALL
Definition: platform.hpp:85