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

sql: avoid copying ColumnDescriptors in initColsForScan #50727

Merged
merged 1 commit into from
Jun 29, 2020

Conversation

nvanbenschoten
Copy link
Member

This change switches scanNode from constructing and passing around a []ColumnDescriptor to constructing and passing around a []*ColumnDescriptor which references the existing ColumnDescriptors in the TableDescriptor. This is in response to seeing the allocation in initColsForScan pop up as the single largest source of total heap allocations by size (alloc_space, the heap profile sample that most closely measures GC pressure) while running TPC-E. The allocation in initColsForScan was responsible for 4.1% of the alloc_space profile after a 30 minute run of the workload.

In general, this indicates that we should move away from copying around these ColumnDescriptors by value. They are currently 120 bytes large, which isn't huge, but also isn't small. Furthermore, unlike TableDescriptors, we almost never pass around only a single ColumnDescriptor. Instead, we're usually operating on every column touched by a query, so this 120 bytes can blow up fast. For instance, if we estimate that the average TPC-E query touches somewhere between 8 and 10 columns then a single copy of all of these descriptors during the execution of a query (like we were doing in initColsForScan) requires allocating and copying over 1KB of memory.

Yahor, I'm assigning you for two reasons. One, because you seem to be working most closely to this code and likely have a good idea for how disruptive this kind of change will be. I don't want to split the world into functions that work with []ColumnDescriptor and functions that work with []*ColumnDescriptor. I also figured you'd be interested to know that I was running this using an older SHA and the second and third largest sources of allocations were in createTableReaders (3.54%) and ColumnTypesWithMutations (2.60%). Both had to do with constructing slices of types.T and both appear to have been fixed by c06277e. So nice job with that change!

This change switches `scanNode` from constructing and passing around a
[]ColumnDescriptor to constructing and passing around a []*ColumnDescriptor.
This is in response to seeing the allocation in `initColsForScan` pop up as
the single largest source of total heap allocations by size (`alloc_space`,
the heap profile sample that most closely measures GC pressure) while running
TPC-E. The allocation in `initColsForScan` was responsible for **4.1%** of
the `alloc_space` profile after a 30 minute run of the workload.

In general, this indicates that we should move away from copying around these
ColumnDescriptors by value. They are currently 120 bytes large, which isn't
huge, but also isn't small. Furthermore, unlike TableDescriptors, we almost
never pass around only a single ColumnDescriptor. Instead, we're usually
operating on every column touched by a query, so this 120 bytes can blow up
fast. For instance, if we estimate that the average TPC-E query touches
somewhere between 8 and 10 columns then a single copy of all of these
descriptors during the execution of a query (like we were doing in
initColsForScan) requires allocating and copying over 1KB of memory.

Yahor, I'm assigning you for two reasons. One, because you seem to be working
most closely to this code and likely have a good idea for how disruptive this
kind of change will be. I don't want to split the world into functions that
work with []ColumnDescriptor and functions that work with []*ColumnDescriptor.
I also figured you'd be interested to know that I was running this using an
older SHA and the second and third largest sources of allocations were in
`createTableReaders` (3.54%) and `ColumnTypesWithMutations` (2.60%). Both
had to do with constructing slices of `types.T` and both appear to have been
fixed by c06277e. So nice job with that change!
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Member

@yuzefovich yuzefovich left a comment

Choose a reason for hiding this comment

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

Nice find! :lgtm:

the second and third largest sources of allocations were in
createTableReaders (3.54%) and ColumnTypesWithMutations (2.60%). Both
had to do with constructing slices of types.T and both appear to have been
fixed by c06277e.

Wohoo!

how disruptive this kind of change will be

I think it is reasonable to introduce such "duplicity" of some methods given the performance gain we get. And I agree with your sentiment that it seems like we should be moving away from copying the column descriptors by value, and this change does a first step towards that bright future :)

Reviewed 4 of 4 files at r1.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained

@nvanbenschoten
Copy link
Member Author

TFTR!

bors r+

@craig
Copy link
Contributor

craig bot commented Jun 29, 2020

Build succeeded

@craig craig bot merged commit dbb5ad1 into cockroachdb:master Jun 29, 2020
@nvanbenschoten nvanbenschoten deleted the nvanbenschoten/colDescCpy branch June 30, 2020 20:31
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.

3 participants