Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce priorities in ThreadPool #2092

Merged
merged 4 commits into from
Jul 9, 2020

Conversation

jantonguirao
Copy link
Contributor

Signed-off-by: Joaquin Anton janton@nvidia.com

Why we need this PR?

  • It adds new feature needed because of we want to be able to post work to a thread pool that will be executed according to its priority

What happened in this PR?

Fill relevant points, put NA otherwise. Replace anything inside []

  • What solution was applied:
    Added a priority queue in ThreadPool
    Added a new pattern of using ThreadPool: AddWork will add work to the queue but won't start processing it, and RunAll will wake up all the threads to process the remaining work, which will be picked in order according to the task priority
  • Affected modules and functionalities:
    Thread pool
  • Key points relevant for the review:
    Thread pool implementation
  • Validation and testing:
    Unit tests and benchmark added
  • Documentation (including examples):
    Doxygen

TODO as a follow-up: Modify all uses of ThreadPool in DALI operators to use the new AddWork/RunAll pattern

JIRA TASK: [DALI-1473]

@jantonguirao jantonguirao requested a review from a team July 7, 2020 14:50
* @brief Adds work to the queue with optional priority.
* The work only gets queued and it will only start after invoking
* `RunAll` (wakes up all threads to complete all remaining works) or
* `RunWork` (wakes up a single thread to complete one work unit).
Copy link
Contributor

@JanuszL JanuszL Jul 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see RunWork implemented.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it should be DoWorkWithID

return a.first < b.first;
}
};
std::queue<Work> work_queue__;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove


void ThreadPool::DoWorkWithID(Work work, int64_t priority) {
AddWork(std::move(work), priority);
adding_work_ = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not lock protected change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

tl_errors_[i].pop();
throw std::runtime_error(error);
}
}
}
}

void ThreadPool::RunAll(bool wait) {
adding_work_ = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not lock protected change.

adding_work_ = true;
}

void ThreadPool::DoWorkWithID(Work work, int64_t priority) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:

void ThreadPool::DoWorkWithID(Work work, int64_t priority, bool hold_work = false) {
  AddWork(std::move(work), priority, hold_work );
  condition_.notify_one();
}

void ThreadPool::AddWork(Work work, int64_t priority, bool hold_work = true) {
  std::lock_guard<std::mutex> lock(mutex_);
  work_queue_.push({priority, std::move(work)});
  work_complete_ = false;
  adding_work_ = hold_work ;
}

std::lock_guard<std::mutex> lock(mutex_);
adding_work_ = false;
}
condition_.notify_all();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can be notify_one(). Worker threads already have a mechanism to notify a next worker if there is a task pending. In case the number of jobs is smaller than number of workers notify_all() would wake more threads than needed.

Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
@jantonguirao
Copy link
Contributor Author

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1455543]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1455543]: BUILD FAILED

Signed-off-by: Joaquin Anton <janton@nvidia.com>
@jantonguirao
Copy link
Contributor Author

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1455678]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1455678]: BUILD PASSED

@jantonguirao jantonguirao merged commit cdac7fc into NVIDIA:master Jul 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants