// return the delay bound to use for this job/host. // Actually, return two: optimistic (lower) and pessimistic (higher). // If the deadline check with the optimistic bound fails, // try the pessimistic bound. // TODO: clean up this mess // static void get_delay_bound_range( WORKUNIT& wu, int res_server_state, int res_priority, double res_report_deadline, BEST_APP_VERSION& bav, double& opt, double& pess ) { if (res_server_state == RESULT_SERVER_STATE_IN_PROGRESS) { double now = dtime(); if (res_report_deadline < now) { // if original deadline has passed, return zeros // This will skip deadline check. opt = pess = 0; return; } opt = res_report_deadline - now; pess = wu.delay_bound; } else { opt = pess = wu.delay_bound; // If the workunit needs reliable and is being sent to a reliable host, // then shorten the delay bound by the percent specified // if (config.reliable_on_priority && res_priority >= config.reliable_on_priority && config.reliable_reduced_delay_bound > 0.01 ) { opt = wu.delay_bound*config.reliable_reduced_delay_bound; double est_wallclock_duration = estimate_duration(wu, bav); // Check to see how reasonable this reduced time is. // Increase it to twice the estimated delay bound // if all the following apply: // // 1) Twice the estimate is longer then the reduced delay bound // 2) Twice the estimate is less then the original delay bound // 3) Twice the estimate is less then the twice the reduced delay bound if (est_wallclock_duration*2 > opt && est_wallclock_duration*2 < wu.delay_bound && est_wallclock_duration*2 < wu.delay_bound*config.reliable_reduced_delay_bound*2 ) { opt = est_wallclock_duration*2; } } } }
// Assign a new deadline for the result; // if it's not likely to complete by this time, return nonzero. // TODO: EXPLAIN THE FORMULA FOR NEW DEADLINE // static int possibly_give_result_new_deadline( DB_RESULT& result, WORKUNIT& wu, BEST_APP_VERSION& bav ) { const double resend_frac = 0.5; // range [0, 1) int now = time(0); int result_report_deadline = now + (int)(resend_frac*(result.report_deadline - result.sent_time)); if (result_report_deadline < result.report_deadline) { result_report_deadline = result.report_deadline; } if (result_report_deadline > now + wu.delay_bound) { result_report_deadline = now + wu.delay_bound; } // If infeasible, return without modifying result // if (estimate_duration(wu, bav) > result_report_deadline-now) { if (config.debug_resend) { log_messages.printf(MSG_NORMAL, "[resend] [RESULT#%u] [HOST#%d] not resending lost result: can't complete in time\n", result.id, g_reply->host.id ); } return 1; } // update result with new report time and sent time // if (config.debug_resend) { log_messages.printf(MSG_NORMAL, "[resend] [RESULT#%u] [HOST#%d] %s report_deadline (resend lost work)\n", result.id, g_reply->host.id, result_report_deadline==result.report_deadline?"NO update to":"Updated" ); } result.sent_time = now; result.report_deadline = result_report_deadline; return 0; }
// return 0 if the job, with the given delay bound, // will complete by its deadline, and won't cause other jobs to miss deadlines. // static inline int check_deadline( WORKUNIT& wu, APP& app, BEST_APP_VERSION& bav ) { if (config.ignore_delay_bound) return 0; // skip delay check if host currently doesn't have any work // and it's not a hard app. // (i.e. everyone gets one result, no matter how slow they are) // if (get_estimated_delay(bav) == 0 && !hard_app(app)) { if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[send] est delay 0, skipping deadline check\n" ); } return 0; } // if it's a hard app, don't send it to a host with no credit // if (hard_app(app) && g_reply->host.total_credit == 0) { return INFEASIBLE_CPU; } // do EDF simulation if possible; else use cruder approximation // if (config.workload_sim && g_request->have_other_results_list) { double est_dur = estimate_duration(wu, bav); if (g_reply->wreq.edf_reject_test(est_dur, wu.delay_bound)) { return INFEASIBLE_WORKLOAD; } IP_RESULT candidate("", wu.delay_bound, est_dur); safe_strcpy(candidate.name, wu.name); if (check_candidate(candidate, g_wreq->effective_ncpus, g_request->ip_results)) { // it passed the feasibility test, // but don't add it to the workload yet; // wait until we commit to sending it } else { g_reply->wreq.edf_reject(est_dur, wu.delay_bound); g_reply->wreq.speed.set_insufficient(0); return INFEASIBLE_WORKLOAD; } } else { double ewd = estimate_duration(wu, bav); if (hard_app(app)) ewd *= 1.3; double est_report_delay = get_estimated_delay(bav) + ewd; double diff = est_report_delay - wu.delay_bound; if (diff > 0) { if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[send] [WU#%u] deadline miss %d > %d\n", wu.id, (int)est_report_delay, wu.delay_bound ); } g_reply->wreq.speed.set_insufficient(diff); return INFEASIBLE_CPU; } else { if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[send] [WU#%u] meets deadline: %.2f + %.2f < %d\n", wu.id, get_estimated_delay(bav), ewd, wu.delay_bound ); } } } return 0; }
void open(const std::string& filename, VideoInfo& info) { std::cerr << "load_file_start:'" << filename << "'\n"; AVFormatParameters params; memset(¶ms, 0, sizeof(params)); params.initial_pause = 1; // open input file without format or bufffer size // (let ffmpeg try autodetection) int err = av_open_input_file(&av_fc, filename.c_str(), 0, 0, ¶ms); if (err < 0) { std::cerr << "err = " << err << "\n"; throw std::runtime_error("could not open file"); } err = av_find_stream_info(av_fc); if (err < 0) { close(); throw std::runtime_error("Could not find codec parameters\n"); } // look for the video stream int stream_index = -1; for (int i = 0; i < av_fc->nb_streams; i++) { AVCodecContext* enc = av_fc->streams[i]->codec; if (enc->codec_type == CODEC_TYPE_VIDEO) { stream_index = i; break; } } if (stream_index == -1) { close(); throw std::runtime_error("Could not find any video streams in file"); } // some debug info dump_format(av_fc, 0, filename.c_str(), 0); dump_stream_info(av_fc); try { open_stream(av_fc, stream_index); video_stream_index = stream_index; } catch (...) { close(); throw; } AVCodecContext* enc = av_fc->streams[video_stream_index]->codec; if (enc->width == 0) { close(); throw std::runtime_error("No width and height"); } AVStream* video_stream = av_fc->streams[video_stream_index]; m_fps = av_q2d(video_stream->r_frame_rate); double duration_s; int ret = estimate_duration(av_fc, video_stream_index, m_fps, &duration_s, &m_start_time); if (ret < 0) { close(); throw std::runtime_error("Could not estimate stream duration"); } int num_frames = static_cast<int>(floor(av_q2d(video_stream->r_frame_rate) * duration_s)); info.width = enc->width; info.height = enc->height; info.num_frames = num_frames; m_width = info.width; m_height = info.height; m_num_frames = info.num_frames; std::cout << "(width x height) = (" << info.width << "x" << info.height <<")\n"; std::cout << "#frames = " << info.num_frames << "\n"; m_current_timestamp = -100; std::cout << "duration : " << duration_s << "s (" << (double) video_stream->duration * av_q2d(video_stream->time_base) << " s)\n"; std::cout << "start_time: " << m_start_time << " s\n"; std::cout << "fps : " << m_fps << "\n"; std::cout << "timebase : " << av_q2d(video_stream->time_base) << "\n"; m_frame = avcodec_alloc_frame(); file_name = filename; m_bytes_left = 0; m_scale_buf = 0; m_scale_buf_size = 0; }