-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
GH-43129: [C++][Compute] Fix the unnecessary allocation of extra bytes when encoding row table #43125
GH-43129: [C++][Compute] Fix the unnecessary allocation of extra bytes when encoding row table #43125
Conversation
Thanks for opening a pull request! If this is not a minor PR. Could you open an issue for this pull request on GitHub? https://github.com/apache/arrow/issues/new/choose Opening GitHub issues ahead of time contributes to the Openness of the Apache Arrow project. Then could you also rename the pull request title in the following format?
or
In the case of PARQUET issues on JIRA the title also supports:
See also: |
@github-actions crossbow submit -g cpp |
7b6682c
to
342a91d
Compare
Revision: 7b6682c Submitted crossbow builds: ursacomputing/crossbow @ actions-ea31ebc24b |
@github-actions crossbow submit -g cpp |
Revision: 8619d9e Submitted crossbow builds: ursacomputing/crossbow @ actions-adf44107b5 |
@github-actions crossbow submit -g cpp |
Revision: daf6d15 Submitted crossbow builds: ursacomputing/crossbow @ actions-29d3b99634 |
daf6d15
to
b8ff724
Compare
Hi @pitrou @westonpace , mind to take a look? This fix reduces the memory footprint of row table almost by half so could be a major improvement. Thanks. |
|
||
TEST(RowTableMemoryConsumption, Encode) { | ||
constexpr int64_t num_rows_max = 8192; | ||
constexpr int64_t padding_for_vectors = 64; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refers to this
static constexpr int64_t kPaddingForVectors = 64; |
which is always appended to the needed capacity when resizing buffers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay @zanmato1984 !
- can you rebase?
- please find comments below
@@ -158,8 +158,7 @@ Status RowTableEncoder::EncodeSelected(RowTableImpl* rows, uint32_t num_selected | |||
EncoderOffsets::GetRowOffsetsSelected(rows, batch_varbinary_cols_, num_selected, | |||
selection); | |||
|
|||
RETURN_NOT_OK(rows->AppendEmpty(static_cast<uint32_t>(0), | |||
static_cast<uint32_t>(rows->offsets()[num_selected]))); | |||
RETURN_NOT_OK(rows->AppendEmpty(static_cast<uint32_t>(0), static_cast<uint32_t>(0))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add parameter names to make sure we understand what's being passed?
RETURN_NOT_OK(rows->AppendEmpty(static_cast<uint32_t>(0), static_cast<uint32_t>(0))); | |
RETURN_NOT_OK(rows->AppendEmpty(/*xxx=*/ static_cast<uint32_t>(0), /*yyy=*/ static_cast<uint32_t>(0))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
int64_t actual_null_mask_size = | ||
num_rows * row_table.metadata().null_masks_bytes_per_row; | ||
ASSERT_GT(actual_null_mask_size * 2, | ||
row_table.buffer_size(0) - padding_for_vectors); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also check that the buffer size is large enough? Same for other inequalities below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, will add them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
} // namespace | ||
|
||
TEST(RowTableMemoryConsumption, Encode) { | ||
constexpr int64_t num_rows_max = 8192; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment and GH issue reference to explain what this test is checking for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
f202c1a
to
185a73c
Compare
Rebase done. |
After merging your PR, Conbench analyzed the 4 benchmarking runs that have been run so far on merge-commit 3b7ad9d. There were no benchmark performance regressions. 🎉 The full Conbench report has more details. It also includes information about 47 possible false positives for unstable benchmarks that are known to sometimes produce them. |
Rationale for this change
As described in #43129 , current row table occupies more memory than expected. The memory consumption is double of necessary. The reason listed below.
When encoding var length columns into into the row table:
arrow/cpp/src/arrow/compute/row/encode_internal.cc
Lines 155 to 162 in e59832f
We first call
AppendEmpty
to reserve space forx
rows but0
bytes. This is to reserve enough size for the underlying fixed-length buffers: null masks and offsets (for var-length columns).Then we call
GetRowOffsetsSelected
to populate the offsets.At last we call
AppendEmpty
again with0
rows buty
bytes, wherey
is the last offset element which is essentially the whole size of the var-length columns.Sounds all reasonable so far.
However,
AppendEmpty
callsResizeOptionalVaryingLengthBuffer
, in which:arrow/cpp/src/arrow/compute/row/row_internal.cc
Lines 294 to 303 in e59832f
We calculate
bytes_capacity_new
by keeping doubling it until it's big enough fornum_bytes + num_extra_bytes
.Note by the time of this point,
num_bytes == offsets()[num_rows_]
is alreadyy
, meanwhilenum_extra_bytes
is alsoy
, hence the unexpected doubled size than necessary.What changes are included in this PR?
Fix the wasted half size for buffers in row table. Also add tests to make sure the buffer size is as expected.
Are these changes tested?
UT included.
Are there any user-facing changes?
None.