34 namespace async_schedule_local {
36 constexpr
static bool debug =
false;
43 inline sim_event(
size_t t,
size_t b) :
timestamp(t), iblock(b) { }
46 struct sim_event_cmp :
public std::binary_function<sim_event, sim_event, bool>
48 inline bool operator () (
const sim_event& a,
const sim_event& b)
const 50 return a.timestamp > b.timestamp;
55 struct write_time_cmp :
public std::binary_function<write_time_pair, write_time_pair, bool>
59 return a.second > b.second;
63 static inline size_t get_disk(
size_t i,
const size_t* disks,
size_t D)
65 size_t disk = disks[i];
77 std::pair<size_t, size_t>* o_time)
79 using event_queue_type = std::priority_queue<sim_event, std::vector<sim_event>, sim_event_cmp>;
80 using disk_queue_type = std::queue<size_t>;
84 event_queue_type event_queue;
96 disk_queues[disk].push(i);
99 for (
size_t ii = 0; ii <=
D; ii++)
100 if (!disk_queues[ii].empty())
102 size_t j = disk_queues[ii].front();
103 disk_queues[ii].pop();
104 event_queue.push(sim_event(1, j));
105 TLX_LOG <<
"Block " << j <<
" scheduled";
108 while (!event_queue.empty())
110 sim_event cur = event_queue.top();
112 if (oldtime != cur.timestamp)
115 for (
size_t j = 0; j <=
D; j++)
116 disk_busy[j] =
false;
118 oldtime = cur.timestamp;
121 TLX_LOG <<
"Block " << cur.iblock <<
" put out, time " 122 << cur.timestamp <<
" disk: " << disks[cur.iblock];
123 o_time[cur.iblock] = std::pair<size_t, size_t>(cur.iblock, cur.timestamp);
127 size_t disk =
get_disk(i - 1, disks, D);
130 disk_queues[disk].push(--i);
134 if (!disk_queues[disk].empty())
136 TLX_LOG <<
"c Block " << disk_queues[disk].front()
137 <<
" scheduled for time " << cur.timestamp + 1;
138 event_queue.push(sim_event(cur.timestamp + 1, disk_queues[disk].front()));
139 disk_queues[disk].pop();
143 TLX_LOG <<
"a Block " << (i - 1)
144 <<
" scheduled for time " << cur.timestamp + 1;
145 event_queue.push(sim_event(cur.timestamp + 1, --i));
147 disk_busy[disk] =
true;
152 size_t disk =
get_disk(cur.iblock, disks, D);
153 if (!disk_busy[disk] && !disk_queues[disk].empty())
155 TLX_LOG <<
"b Block " << disk_queues[disk].front()
156 <<
" scheduled for time " << cur.timestamp + 1;
157 event_queue.push(sim_event(cur.timestamp + 1, disk_queues[disk].front()));
158 disk_queues[disk].pop();
159 disk_busy[disk] =
true;
164 for (
size_t j = 0; j <=
D; j++)
165 assert(disk_queues[j].empty());
167 return (oldtime - 1);
179 constexpr
bool debug =
false;
181 using pair_type = std::pair<size_t, size_t>;
182 size_t L = last - first;
185 for (
size_t i = 0; i < L; ++i)
190 pair_type* write_order =
new pair_type[L];
194 TLX_LOG <<
"Write steps: " << w_steps;
196 for (
size_t i = 0; i < L; i++)
197 TLX_LOG << first[i] <<
" " << write_order[i].first <<
" " << write_order[i].second;
199 std::stable_sort(write_order, write_order + L, async_schedule_local::write_time_cmp());
201 for (
size_t i = 0; i < L; i++)
203 out_first[i] = write_order[i].first;
205 TLX_LOG << i <<
" " << out_first[i];
208 delete[] write_order;
static size_t get_disk(size_t i, const size_t *disks, size_t D)
static const unsigned int DEFAULT_DEVICE_ID
Simpler non-growing vector without initialization.
void compute_prefetch_schedule(const size_t *first, const size_t *last, size_t *out_first, size_t m, size_t D)
static double timestamp()
Returns number of seconds since the epoch, high resolution.
static constexpr bool debug
std::pair< size_t, size_t > write_time_pair
size_t simulate_async_write(const size_t *disks, const size_t L, const size_t m_init, const size_t D, std::pair< size_t, size_t > *o_time)
#define TLX_LOG
Default logging method: output if the local debug variable is true.