Skip to content

ARROW-17824: [C++][Gandiva] Implement preallocation for variable length output buffer - #14230

Merged
kou merged 2 commits into
apache:masterfrom
js8544:jinshang/gandiva-preallocation-output
Sep 26, 2022
Merged

kou merged 2 commits into
apache:masterfrom
js8544:jinshang/gandiva-preallocation-output

Conversation

@js8544

@js8544 js8544 commented Sep 24, 2022

Copy link
Copy Markdown
Contributor

When the output type of an expression is of variable length, e.g. string, Gandiva would realloc the output buffer to make space for new outputs for each row. When num of rows is high some memory allocators perform poorly.

We can use the std::vector like approach to amortize the allcation cost. First allocate some initial space depending on the input size. Each time we run out of space, double the buffer size. In the end shrink it to fit the actual size. Arrow string builder also uses this approach.

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

⚠️ Ticket has not been started in JIRA, please click 'Start Progress'.

@js8544

js8544 commented Sep 24, 2022 •

Copy link
Copy Markdown
Contributor Author

I've tested the performance with a newly added benchmark TimedTestOutputStringAllocs.
On my machine, it changes from 361038us to 290553us for jemalloc, and 6765325us to 291024us for mimalloc. Huge improvement for mimalloc.

@js8544
js8544 force-pushed the jinshang/gandiva-preallocation-output branch from b42d3d1 to c82be89 Compare September 24, 2022 17:51

@kou kou left a comment

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.

+1

Comment thread cpp/src/gandiva/gdv_function_stubs.cc Resolved
@js8544
js8544 force-pushed the jinshang/gandiva-preallocation-output branch from c82be89 to 79a62fb Compare September 25, 2022 01:22
Comment on lines 275 to 277

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.

Could you use the target expression directly with ASSERT_OK() to get better failure message?

Suggested change
auto status = TimedEvaluate<arrow::StringType, std::string>(
schema, evaluator, data_generator, pool_, 1 * MILLION, 16 * THOUSAND, state);
ASSERT_OK(status);
ASSERT_OK(TimedEvaluate<arrow::StringType, std::string>(
schema, evaluator, data_generator, pool_, 1 * MILLION, 16 * THOUSAND, state));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I tried this but it doesn't compile.

/home/jinshang/arrow/cpp/src/gandiva/tests/micro_benchmarks.cc:312:138: error: macro "ASSERT_OK" passed 2 arguments, but takes just 1
  312 |   ASSERT_OK(TimedEvaluate<arrow::StringType, std::string>(schema, evaluator, data_generator, pool_, 100 * THOUSAND, 16 * THOUSAND, state));
      |                                                                                                                                          ^
In file included from /home/jinshang/arrow/cpp/src/gandiva/tests/micro_benchmarks.cc:21:
/home/jinshang/arrow/cpp/src/arrow/testing/gtest_util.h:87: note: macro "ASSERT_OK" defined here
   87 | #define ASSERT_OK(expr)                                                              \
      | 
/home/jinshang/arrow/cpp/src/gandiva/tests/micro_benchmarks.cc: In function ‘void gandiva::TimedTestMultiOr(benchmark::State&)’:
/home/jinshang/arrow/cpp/src/gandiva/tests/micro_benchmarks.cc:312:3: error: ‘ASSERT_OK’ was not declared in this scope
  312 |   ASSERT_OK(TimedEvaluate<arrow::StringType, std::string>(schema, evaluator, data_generator, pool_, 100 * THOUSAND, 16 * THOUSAND, state));

Seems to be linked to this: https://stackoverflow.com/questions/32241581/c-preprocessors-are-not-aware-of-template-arguments
So I wrapped an additional pair of parentheses and it works now.

@js8544
js8544 force-pushed the jinshang/gandiva-preallocation-output branch 2 times, most recently from 6caaeab to 77527c6 Compare September 26, 2022 02:56
@kou

kou commented Sep 26, 2022

Copy link
Copy Markdown
Member

Thanks!

@kou
kou merged commit cc76736 into apache:master Sep 26, 2022
@ursabot

ursabot commented Sep 26, 2022

Copy link
Copy Markdown

Benchmark runs are scheduled for baseline = b76ddf1 and contender = cc76736. cc76736 is a master commit associated with this PR. Results will be available as each benchmark for each run completes.
Conbench compare runs links:
[Finished ⬇️0.0% ⬆️0.0%] ec2-t3-xlarge-us-east-2
[Failed ⬇️0.41% ⬆️0.07%] test-mac-arm
[Failed ⬇️0.0% ⬆️0.27%] ursa-i9-9960x
[Finished ⬇️0.5% ⬆️0.04%] ursa-thinkcentre-m75q
Buildkite builds:
[Finished] cc767365 ec2-t3-xlarge-us-east-2
[Finished] cc767365 test-mac-arm
[Failed] cc767365 ursa-i9-9960x
[Finished] cc767365 ursa-thinkcentre-m75q
[Finished] b76ddf19 ec2-t3-xlarge-us-east-2
[Failed] b76ddf19 test-mac-arm
[Failed] b76ddf19 ursa-i9-9960x
[Finished] b76ddf19 ursa-thinkcentre-m75q
Supported benchmarks:
ec2-t3-xlarge-us-east-2: Supported benchmark langs: Python, R. Runs only benchmarks with cloud = True
test-mac-arm: Supported benchmark langs: C++, Python, R
ursa-i9-9960x: Supported benchmark langs: Python, R, JavaScript
ursa-thinkcentre-m75q: Supported benchmark langs: C++, Java

zagto pushed a commit to zagto/arrow that referenced this pull request Oct 7, 2022
…th output buffer (apache#14230)

When the output type of an expression is of variable length, e.g. string, Gandiva would realloc the output buffer to make space for new outputs for each row. When num of rows is high some memory allocators perform poorly.

We can use the std::vector like approach to amortize the allcation cost. First allocate some initial space depending on the input size. Each time we run out of space, double the buffer size. In the end shrink it to fit the actual size. Arrow string builder also uses this approach.

Authored-by: Jin Shang <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
@js8544
js8544 deleted the jinshang/gandiva-preallocation-output branch October 11, 2022 08:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants