void OrderedTask::GlideSolutionPlanned(const AircraftState &aircraft, const GlidePolar &glide_polar, GlideResult &total, GlideResult &leg, DistanceStat &total_remaining_effective, DistanceStat &leg_remaining_effective, const GlideResult &solution_remaining_total, const GlideResult &solution_remaining_leg) { TaskMacCreadyTotal tm(task_points, active_task_point, task_behaviour.glide, glide_polar); total = tm.glide_solution(aircraft); leg = tm.get_active_solution(); if (solution_remaining_total.IsOk()) total_remaining_effective.SetDistance(tm.effective_distance(solution_remaining_total.time_elapsed)); else total_remaining_effective.Reset(); if (solution_remaining_leg.IsOk()) leg_remaining_effective.SetDistance(tm.effective_leg_distance(solution_remaining_leg.time_elapsed)); else leg_remaining_effective.Reset(); }
static void Copy(DistanceStat &stat, const GlideResult &solution) { if (solution.IsDefined()) stat.set_distance(solution.vector.distance); else stat.Reset(); }
void DistanceStatComputer::CalcSpeed(DistanceStat &data, fixed time) { if (positive(time) && data.IsDefined()) data.speed = data.GetDistance() / time; else data.speed = fixed_zero; }
void DistanceStatComputer::ResetIncrementalSpeed(DistanceStat &data) { fixed distance = data.IsDefined() ? data.GetDistance() : fixed_zero; fixed speed = data.IsDefined() ? data.GetSpeed() : fixed_zero; df.Reset(distance, (is_positive ? -1 : 1) * speed); v_lpf.Reset((is_positive ? -1 : 1) * speed); data.speed_incremental = fixed_zero; // data.speed; av_dist.Reset(); }
void IncrementalSpeedComputer::Reset(DistanceStat &data) { fixed distance = data.IsDefined() ? data.GetDistance() : fixed(0); fixed speed = data.IsDefined() ? data.GetSpeed() : fixed(0); df.Reset(distance, (is_positive ? -1 : 1) * speed); v_lpf.Reset((is_positive ? -1 : 1) * speed); data.speed_incremental = fixed(0); // data.speed; av_dist.Reset(); last_time = fixed(-1); }
void DistanceStatComputer::CalcIncrementalSpeed(DistanceStat &data, const fixed dt) { if ((dt + fixed_half >= fixed_one) && data.IsDefined()) { if (av_dist.Update(data.distance)) { const fixed d_av = av_dist.Average() / N_AV; av_dist.Reset(); fixed v_f = fixed_zero; for (unsigned i = 0; i < (unsigned)(dt + fixed_half); ++i) { const fixed v = df.Update(d_av); v_f = v_lpf.Update(v); } data.speed_incremental = (is_positive ? -v_f : v_f); } } else if (!positive(dt) || !data.IsDefined()) { ResetIncrementalSpeed(data); } }
void UnorderedTask::GlideSolutionPlanned(const AircraftState &state, GlideResult &total, GlideResult &leg, DistanceStat &total_remaining_effective, DistanceStat &leg_remaining_effective, const GlideResult &solution_remaining_total, const GlideResult &solution_remaining_leg) { total = solution_remaining_total; leg = solution_remaining_leg; if (total.IsOk()) total_remaining_effective.set_distance(total.vector.distance); else total_remaining_effective.Reset(); if (leg.IsOk()) leg_remaining_effective.set_distance(leg.vector.distance); else leg_remaining_effective.Reset(); }
static void CalculatePirker(DistanceStat &pirker, const DistanceStat &planned, const DistanceStat &remaining_effective) { if (planned.IsDefined() && remaining_effective.IsDefined()) pirker.set_distance(planned.get_distance() - remaining_effective.get_distance()); else pirker.Reset(); }
void IncrementalSpeedComputer::Compute(DistanceStat &data, const fixed time) { if (!data.IsDefined() || negative(time) || (!negative(last_time) && (time < last_time || time > last_time + fixed(60)))) { Reset(data); return; } if (negative(last_time)) { last_time = time; return; } const fixed dt = time - last_time; const unsigned seconds = uround(dt); if (seconds == 0) return; if (!av_dist.Update(data.distance)) return; const fixed d_av = av_dist.Average(); av_dist.Reset(); fixed v_f = fixed(0); for (unsigned i = 0; i < seconds; ++i) { const fixed v = df.Update(d_av); v_f = v_lpf.Update(v); } last_time += fixed(seconds); data.speed_incremental = (is_positive ? -v_f : v_f); }
void calculate_reuse_distance(AnalyseTask & task, ModelConfig & model_config, DistanceStat & stat) { int i; int fake_stamp; // Record number of memory access WarpAccess * p_warp_access; int set_id; // The normal latency genenrator NormalGenerator normal_generator(model_config.latency_mean, model_config.latency_dev); // Variable to record on going requests // Meant for mshr check std::multimap<addr_type, int> ongoing_requests; // Calculate total number of accesses for each set std::vector<int> total_accesses_per_set; task.reset(); total_accesses_per_set.resize(model_config.cache_set_size, 0); p_warp_access = task.next_warp_access(0); while (p_warp_access != NULL) { for (i = 0; i < p_warp_access->size; i++) { set_id = calculate_cache_set(p_warp_access->accesses[i], model_config); total_accesses_per_set[set_id] ++; } p_warp_access = task.next_warp_access(0); } // Create a tree data structure for each set (B in the Almasi et al. paper) std::vector<Tree> Bs; Bs.reserve(model_config.cache_set_size); for (set_id = 0; set_id < model_config.cache_set_size; set_id ++) { Bs.emplace_back(total_accesses_per_set[set_id] + STACK_EXTRA_SIZE); } // Create the hash data structure (P in the Almasi et al. paper) std::vector<std::map<addr_type, int>> Ps; Ps.reserve(model_config.cache_set_size); Ps.resize(model_config.cache_set_size); // Record processed number of accesses per cache set std::vector<int> set_counters; set_counters.resize(model_config.cache_set_size); for (i = 0; i < set_counters.size(); i++) set_counters[i] = 0; // Start the main loop fake_stamp = 0; task.reset(); while (! task.is_finish()) { // Process ongoing requests at eache new time stamp process_ongoing_requests(ongoing_requests, fake_stamp, Bs, Ps, set_counters, model_config); // If all warps are jamed, get a NULL pointer, and thuns increase fake_stamp and continue p_warp_access = task.next_warp_access(fake_stamp); if (p_warp_access == NULL) { fake_stamp ++; continue; } // Take a warptrace // If MSHR check fails // Increast fake_stamp to a point where more mshrs will be available while (p_warp_access->size + ongoing_requests.size() > model_config.num_mshrs) { fake_stamp = get_shortest_stamp(ongoing_requests); process_ongoing_requests(ongoing_requests, fake_stamp, Bs, Ps, set_counters, model_config); } // Calculate reuse distance and access latency for each access int max_latency = -1; // max_latency of accesses int the same warp access int latency; for (i = 0; i < p_warp_access->size; i++) { addr_type line_addr; int distance; line_addr = p_warp_access->accesses[i]; // If the model is configed allocate_on_miss, // Calculate reuse distance, and // update the stack immediately, no matter it's a hit or miss if (model_config.allocate_on_miss) { distance = calculate_reuse_distance_update_stack_tree(line_addr, Bs, Ps, set_counters, model_config); } else { // else, just calculate the reuse distance for now distance = calculate_reuse_distance(line_addr, Bs, Ps, model_config); } // Update the final output DistanceStat stat.increase(p_warp_access->pc, distance); // Calculate latency of this access if (distance < model_config.cache_way_size && distance >= 0) { // if (distance < model_config.cache_way_size) { latency = 0; // If the model is configed ad not allocate on miss, // put the access to stack now for a cache hit if (! model_config.allocate_on_miss) { update_stack_tree(line_addr, Bs, Ps, set_counters, model_config); } // In the case of pending hit, the latency is not zero // Pending hit only happens in allocate_on_miss config if (model_config.allocate_on_miss) { std::multimap<addr_type, int>::iterator it; it = ongoing_requests.find(line_addr); if (it != ongoing_requests.end()) { latency = it->second - fake_stamp; } } } else { latency = normal_generator.next_number(); } // Update max_latency if (latency > max_latency) max_latency = latency; // Use the latency to update ongoing_requests if (latency > 0) ongoing_requests.emplace(line_addr, fake_stamp + latency); } // Use the max_latency to update warp_trace jam info if (model_config.jam_instruction) { if (p_warp_access->jam) { task.set_last_warptrace_jam(fake_stamp + max_latency); } } else { // Original version: jam every access task.set_last_warptrace_jam(fake_stamp + max_latency); } // Increast fake_stamp fake_stamp ++; } }