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

Aligned aggregate state #2754 #2808

Merged
merged 8 commits into from
Sep 1, 2018
Merged

Conversation

chenxing-xc
Copy link
Contributor

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

The change is to use aligned aggregate state if it is allocated from arena(the problem occur). During my test, the impact is negligible.

total_size_of_aggregate_states += params.aggregates[i].function->sizeOfData();

// aggreate states are aligned based on maximum requirement
align_aggregate_states = std::max(align_aggregate_states,
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to align all states to maximum alignment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IF we don't align states based on maximum requirement, we cannot guarantee non-first state to match its requirement.
e.g.
the first state need to be aligned by one byte
the second state to be aligned by four bytes.

the states allocated need to be aligned by four bytes.

Copy link
Member

Choose a reason for hiding this comment

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

Ok. I forgot all of them are allocated at once.

@@ -0,0 +1,8 @@
drop table if exists test.orin_test;
Copy link
Member

Choose a reason for hiding this comment

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

Could you please merge with master
(because these changes are already in master)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, yes, I upgrade my private branch.


size_t pos = (size_t)(head->pos);
// next pos match align requirement
pos = (pos & ~(align - 1)) + align;
Copy link
Member

Choose a reason for hiding this comment

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

It will add extra padding even if pos is already aligned.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, Changing it to pos = ((pos-1) & ~(align - 1)) + align;

// Fast code path for non-alignment requirement
if (align <= 1) return alloc(size);

size_t pos = (size_t)(head->pos);
Copy link
Member

Choose a reason for hiding this comment

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

According to style, you should use C++ casts.

Copy link
Member

Choose a reason for hiding this comment

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

uintptr_t is the right type for this purpose.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, I don't use std::align for now because calculating aligned address is so simple.

char * alloc_align(size_t size, size_t align)
{
// Fast code path for non-alignment requirement
if (align <= 1) return alloc(size);
Copy link
Member

Choose a reason for hiding this comment

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

Style.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -124,6 +124,30 @@ class Arena : private boost::noncopyable
return res;
}

/// Get peice of memory with alignment
char * alloc_align(size_t size, size_t align)
Copy link
Member

Choose a reason for hiding this comment

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

This should be named alignedAlloc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


if (unlikely(pos + size > (size_t)(head->end)))
{
addChunk(size);
Copy link
Member

Choose a reason for hiding this comment

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

Better to propagate alignment requirement to addChunk.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm, Don't propagate this to addChunk for now.

@@ -1942,7 +1969,8 @@ void NO_INLINE Aggregator::mergeWithoutKeyStreamsImpl(
AggregatedDataWithoutKey & res = result.without_key;
if (!res)
{
AggregateDataPtr place = result.aggregates_pool->alloc(total_size_of_aggregate_states);
AggregateDataPtr place = result.aggregates_pool->alloc_align(total_size_of_aggregate_states,
Copy link
Member

Choose a reason for hiding this comment

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

Also look at SpecializedAggregator that is used when compile setting is enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, thanks for pointing this out

@alexey-milovidov alexey-milovidov merged commit 6d50925 into ClickHouse:master Sep 1, 2018
@alexey-milovidov alexey-milovidov self-assigned this Sep 1, 2018
@alexey-milovidov
Copy link
Member

Usages of aggregate states:

FunctionsMiscellaneous
FunctionsArray
GraphiteRollupSortedBlockInputStream
SummingSortedBlockInputStream
TotalsHavingBlockInputStream

were forgotten.

@alexey-milovidov
Copy link
Member

alexey-milovidov commented Sep 1, 2018

AggregateFunctionNull
...

alexey-milovidov added a commit that referenced this pull request Sep 1, 2018
}
// extend total_size to next alignment requirement
total_size_of_aggregate_states =
(total_size_of_aggregate_states & ~(next_align_req - 1)) + next_align_req;
Copy link
Member

Choose a reason for hiding this comment

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

Looks like you add a padding of size next_align_req even if the total_size_of_aggregate_states was aligned.

@alexey-milovidov
Copy link
Member

AggregateFunctionForEach

@alexey-milovidov
Copy link
Member

ColumnAggregateFunction::getExtremes

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.

2 participants