【问题标题】:search and find the shortest queue and search after some condition搜索并找到最短队列并在某些条件后搜索
【发布时间】:2013-03-07 14:10:43
【问题描述】:

我正在尝试实现一个任务调度程序,其中我有 n 个任务。我的任务调度器背后的想法是,在一个向量的队列循环中,任务应该被排入队列循环中最短的队列,这是通过以下代码完成的。

#include <vector> 
#include <queue> 
std::vector<std::queue<int> > q
int min_index = 0;
task t // implemented in the other part of the program
std::size_t size = q.size();
for( i=0; i<size; i++){ //accessing loop of queues
    if(q[min_index].size() > q[i].size())
        min_index = i; // Now q[min_index] is the shortest queue
} 
q[min_index].push(Task);

接下来我试图扩展这个范式以减少调度程序的开销时间,而不是每次都搜索最短的队列,而是搜索一些条件,即。在 5 个任务入队后搜索最短队列。

我需要做这样的事情

#include <vector> 
#include <queue> 
std::vector<std::queue<int> > q
task t // implemented in the other part of the program
while(q[min_index].size()!=q[min_index].size()+5) // check whether current min_index  queue's size is increased 5 more times if not goto enqueue
        {
        goto enqueue;
        }

    int min_index = 0;

    std::size_t size = q.size();
    for( i=0; i<size; i++){ //accessing loop of queues
        if(q[min_index].size() > q[i].size())
            min_index = i; // Now q[min_index] is the shortest queue
    } 
    enqueue:  
    q[min_index].push(Task);

有人可以帮助我如何正确进行。在此先感谢

更新 我没有考虑 5(一个随机数),而是想到了一个每次都可靠且近似的数字。所以我想到了获取队列循环的 min_value 大小和 max_value 大小的差异,并每次与计数器进行比较。

// global variables 
std::vector<std::queue<int> > q;
int counter = INT_MAX; // 
int min_index = 0;
int max_size = -1;

void enqueue(scheduler::task new_task) { 
 if ( counter > diff_size ){
  // look for new min and maximum
  std::size_t size = q.size();
  for( i=0; i<size; i++){ 
    if(q[min_index].size() > q[i].size())
     min_index = i; 
       if(q[i].size() > max_size)
        max_size = q[i].size(); 
    diff_size=max_size - min_index;
  } 
  // counter reset
  counter = 0;
 }

 // enqueue in minimum queue
 q[min_index].push(new_task)

 // increase counter
 counter ++;
}

【问题讨论】:

  • 一般来说,你应该只使用一个队列。多个队列几乎总是会增加开销并且导致不太理想的调度。
  • @JerryCoffin 是的,但是一种名为“工作窃取”的著名调度技术使用本地队列到线程,所以我只是想以另一种方式使用相同的想法。
  • 好吧,如果您坚持这样做,最好的方法可能是维护您的队列的优先级队列,优先级基于它们的长度,因此您始终可以轻松访问最短队列。
  • @JerryCoffin 好的,但我尝试了这个,我显着减少了开销时间,而不是使用单个全局队列,但仍然比“工作窃取”慢。所以我要通过这个新的更新来减少开销。你能帮我正确处理更新的部分吗
  • 那么,@billa,您想找到最短的队列,将接下来的 5 个任务添加到其中,然后再进行搜索吗?这样您就不必每次都搜索。这就是你想要的吗?

标签: c++ loops for-loop queue goto


【解决方案1】:

我想我会试试这个(代码确实可以编译,并且确实有效):

#include <vector> 
#include <queue>
#include <cassert>
#include <iostream>
using namespace std;

class multi_queue{
  private:
    typedef std::vector<std::queue<int> > mq_type;
    mq_type q;
    int min_queue;
    int min_queue_inc;
    int max_inc;
    void find_min_queue(){
      max_inc=q[min_queue].size();
      min_queue_inc=0;
      min_queue=0;
      for(int i=1;i<q.size();++i)
        if(q[i].size()<q[min_queue].size())
          min_queue=i;
    }
  public:
    multi_queue(int n) {
      assert(n>0);
      min_queue=0;
      min_queue_inc=0;
      max_inc=5;
      increase_queues(n);
    }
    void increase_queues(int n){ 
      if(n<q.size()) return;
      q.resize(n);
    }
    void push(int item){
      if(min_queue_inc++==max_inc)
        find_min_queue();
      q[min_queue].push(item);
    }
    int queues() const {
      return q.size();
    }
    int pop_from(int qnum){
      assert(qnum>=0);
      assert(qnum<q.size());
      assert(can_pop_from(qnum));
      int temp=q[qnum].front();
      q[qnum].pop();
      return temp;
    }
    bool can_pop_from(int qnum) const {
      return q[qnum].size()>0;
    }
    int largest_queue() const {
      int largest=0;
      for(int i=1;i<q.size();++i)
        if(q[i].size()>q[largest].size())
          largest=i;
      return q[largest].size();
    }
};


int main(){
  multi_queue q(10);
  for(int i=0;i<100;++i){
    cout<<"Current largest queue: "<<q.largest_queue()<<endl;
    cout<<"Pushing: " <<i<<endl;
    q.push(i);
  }

  for(int i=0;i<10;++i)
  for(int j=0;j<100;++j)
    if(q.can_pop_from(i))
      cout<<q.pop_from(i)<<endl;
}

当然,您不想每次都显示q.largest_queue(),因为那样会破坏重点,但我在这里这样做是为了让您能够看到一切正常。

从回答问题的角度来看,重要的方法是push()find_min_queue()

我使用两个状态变量min_queuemin_queue_inc 来跟踪正在发生的事情。

min_queue 总是指向最短的队列。 min_queue_inc 跟踪已添加到该队列的项目数。

push()中,我们检查当前最小队列是否有5个项目添加到其中;如果是这样,是时候看看我们是否应该使用新的最小队列,因此我们调用find_min_queue()

find_min_queue() 重置min_queue_inc,找到最短的队列,并在min_queue 中记录该队列。

根据您要执行的操作,调整变量 max_inc 的行为以满足您的需要。

【讨论】:

  • @richardif 我想根据最小队列的长度而不是 5 来增加大小。我应该改变什么?
  • 我不明白你的要求,@billa。
  • @RichardHere 我们将最小队列的大小增加到 5,然后开始下一个搜索操作,对吗?如果我需要增加最小队列的大小直到 n ,其中 n 是“最小队列的长度”,该怎么办
  • 这对你有用吗,@billa?另请注意,我添加了一些与从多队列中删除元素相关的功能。
  • @billa,您可以简单地将类添加到您的文件中并使用static variable 来实例化它。否则,所有代码都在这里,您应该可以轻松地将其拆分。但是,我建议您尝试找到一种方法来使用类或此类来执行此操作,因为它提供了良好的封装。
猜你喜欢
  • 2015-09-26
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
  • 1970-01-01
相关资源
最近更新 更多