Skip to content

Refactor pipeline executor#19587

Merged
KochetovNicolai merged 33 commits intomasterfrom
refactor-pipeline-executor
Nov 12, 2021
Merged

Refactor pipeline executor#19587
KochetovNicolai merged 33 commits intomasterfrom
refactor-pipeline-executor

Conversation

@KochetovNicolai
Copy link
Copy Markdown
Member

I hereby agree to the terms of the CLA available at: https://yandex.ru/legal/cla/?lang=en

Changelog category (leave one):

  • Not for changelog (changelog entry is not required)

@robot-clickhouse robot-clickhouse added the pr-not-for-changelog This PR should not be mentioned in the changelog label Jan 25, 2021
@KochetovNicolai KochetovNicolai marked this pull request as ready for review January 26, 2021 12:40
@nikitamikhaylov nikitamikhaylov self-assigned this Mar 29, 2021
Copy link
Copy Markdown
Member

@nikitamikhaylov nikitamikhaylov left a comment

Choose a reason for hiding this comment

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

Ok, but it is hard to read in presence of many queue.pop()'. Since we have many kinds of queues like ThreadsQueue, AsyncQueue, why not to introduce another one called Queue. Which will be not just a synonim to std::queue, but will have only three methods: get, push and empty.


data.task = nullptr;

lock.unlock();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can call notify even with locked mutex

if (!expected->executeTask(data, true))
return false;

expected = nullptr;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No need to do this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also why we need CAS-loop here if we have mutex?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We don't use mutex to check if there is stopping pipeline task.
We do it in enterConcurrentReadSection or exitConcurrentReadSection, and it could be slow to use mutex here.
mutex is needed to select a thread which executes task
cas loop is need to select a task to execute

while (auto task = async_task_queue.wait(lock))
{
auto * node = static_cast<ExecutingGraph::Node *>(task.data);
executor_contexts[task.thread_num]->pushAsyncTask(node);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do we schedule async task to the same thread (from which prepare was called) ? Why do we schedule async task to the same thread (from which prepare was called) ? Maybe we can take the random thread or thread with the least number of tasks?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I had an idea that it is safer to continue coroutine from the same thread.
Probably it is not necessary. Just in case.

else
thread_to_wake = threads_queue.popAny();

lock.unlock();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The idea is: if there is a task to execute, we need to wake up a thread.
The rest is a heuristic: it is better to wake up a thread with has some tasks (but only if it is not sleeping).
Probably we can combine those queues somehow and check both conditions ...

{
ExecutingGraph::Node * task = nullptr;

if (!async_tasks.empty())
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
if (!async_tasks.empty())
if (has_async_tasks = !async_tasks.empty(); has_async_tasks)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

And we can delete second if statement

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

but we should check this after pop ...

std::atomic_bool has_async_tasks = false;

/// This objects are used to wait for next available task.
std::condition_variable condvar;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is the worst name for condition_variable :(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

To me it's ok as long as there is one condvar field ...
But I'll try to improve

@nikitamikhaylov nikitamikhaylov marked this pull request as draft September 23, 2021 12:06
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Sep 28, 2021

CLA assistant check
All committers have signed the CLA.

@robot-ch-test-poll1 robot-ch-test-poll1 added the submodule changed At least one submodule changed in this PR. label Oct 27, 2021
@KochetovNicolai
Copy link
Copy Markdown
Member Author

Performance - 61 slower. +8.324x. OMG. Looks like lock form boost is too low :(

@alexey-milovidov
Copy link
Copy Markdown
Member

Now performance look alright and tests have passed. Is it still a draft?

@KochetovNicolai KochetovNicolai marked this pull request as ready for review November 10, 2021 15:01
@KochetovNicolai
Copy link
Copy Markdown
Member Author

@Mergifyio update

@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Nov 11, 2021

update

✅ Branch has been successfully updated

@KochetovNicolai KochetovNicolai merged commit 6623c60 into master Nov 12, 2021
@KochetovNicolai KochetovNicolai deleted the refactor-pipeline-executor branch November 12, 2021 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-not-for-changelog This PR should not be mentioned in the changelog submodule changed At least one submodule changed in this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants