Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: tools/pnacl-llc/ThreadedFunctionQueue.h

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/pnacl-llc/SRPCStreamer.cpp ('k') | tools/pnacl-llc/ThreadedStreamingCache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- ThreadedFunctionQueue.h - Function work units for threads -*- C++ -*-==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef THREADEDFUNCTIONQUEUE_H
11 #define THREADEDFUNCTIONQUEUE_H
12
13 #include <limits>
14
15 #include "llvm/IR/Module.h"
16 #include "llvm/Support/ErrorHandling.h"
17
18 namespace llvm {
19
20 // A "queue" that keeps track of which functions have been assigned to
21 // threads and which functions have not yet been assigned. It does not
22 // actually use a queue data structure and instead uses a number which
23 // tracks the minimum unassigned function ID, expecting each thread
24 // to have the same view of function IDs.
25 class ThreadedFunctionQueue {
26 public:
27 ThreadedFunctionQueue(Module *mod, unsigned NumThreads)
28 : NumThreads(NumThreads),
29 NumFunctions(0),
30 CurrentFunction(0) {
31 assert(NumThreads > 0);
32 size_t Size = 0;
33 for (Module::iterator I = mod->begin(), E = mod->end(); I != E; ++I) {
34 // Only count functions with bodies. At this point nothing should
35 // be "already materialized", so if functions with bodies are
36 // materializable.
37 if (I->isMaterializable() || !I->isDeclaration())
38 Size++;
39 }
40 if (Size > static_cast<size_t>(std::numeric_limits<int>::max()))
41 report_fatal_error("Too many functions");
42 NumFunctions = Size;
43 }
44
45 ~ThreadedFunctionQueue() {}
46
47 // Assign functions in a static manner between threads.
48 bool GrabFunctionStatic(unsigned FuncIndex, unsigned ThreadIndex) const {
49 // Note: This assumes NumThreads == SplitModuleCount, so that
50 // (a) every function of every module is covered by the NumThreads and
51 // (b) no function is covered twice by the threads.
52 assert(ThreadIndex < NumThreads);
53 return FuncIndex % NumThreads == ThreadIndex;
54 }
55
56 // Assign functions between threads dynamically.
57 // Returns true if FuncIndex is unassigned and the calling thread
58 // is assigned functions [FuncIndex, FuncIndex + ChunkSize).
59 // Returns false if the calling thread is not assigned functions
60 // [FuncIndex, FuncIndex + ChunkSize).
61 //
62 // NextIndex will be set to the next unassigned function ID, so that
63 // the calling thread will know which function ID to attempt to grab
64 // next. Each thread may have a different value for the ideal ChunkSize
65 // so it is hard to predict the next available function solely based
66 // on incrementing by ChunkSize.
67 bool GrabFunctionDynamic(unsigned FuncIndex, unsigned ChunkSize,
68 unsigned &NextIndex) {
69 unsigned Cur = CurrentFunction;
70 if (FuncIndex < Cur) {
71 NextIndex = Cur;
72 return false;
73 }
74 NextIndex = Cur + ChunkSize;
75 unsigned Index;
76 if (Cur == (Index = __sync_val_compare_and_swap(&CurrentFunction,
77 Cur, NextIndex))) {
78 return true;
79 }
80 // If this thread did not grab the function, its idea of NextIndex
81 // may be incorrect since ChunkSize can vary between threads.
82 // Reset NextIndex in that case.
83 NextIndex = Index;
84 return false;
85 }
86
87 // Returns a recommended ChunkSize for use in calling GrabFunctionDynamic().
88 // ChunkSize starts out "large" to reduce synchronization cost. However,
89 // it cannot be too large, otherwise it will encompass too many bytes
90 // and defeats streaming translation. Assigning too many functions to
91 // a single thread also throws off load balancing, so the ChunkSize is
92 // reduced when the remaining number of functions is low so that
93 // load balancing can be achieved near the end.
94 unsigned RecommendedChunkSize() const {
95 int RemainingFuncs = NumFunctions - CurrentFunction;
96 int DynamicChunkSize = RemainingFuncs / (NumThreads * 4);
97 return std::max(1, std::min(8, DynamicChunkSize));
98 }
99
100 // Total number of functions with bodies that should be processed.
101 unsigned Size() const {
102 return NumFunctions;
103 }
104
105 private:
106 const unsigned NumThreads;
107 unsigned NumFunctions;
108 volatile unsigned CurrentFunction;
109
110 ThreadedFunctionQueue(
111 const ThreadedFunctionQueue&) LLVM_DELETED_FUNCTION;
112 void operator=(const ThreadedFunctionQueue&) LLVM_DELETED_FUNCTION;
113 };
114
115 } // end namespace llvm
116
117 #endif
OLDNEW
« no previous file with comments | « tools/pnacl-llc/SRPCStreamer.cpp ('k') | tools/pnacl-llc/ThreadedStreamingCache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698