diff --git a/file/random_access_file_reader.cc b/file/random_access_file_reader.cc index d3fb37f78..e38e9ec13 100644 --- a/file/random_access_file_reader.cc +++ b/file/random_access_file_reader.cc @@ -97,6 +97,15 @@ IOStatus RandomAccessFileReader::Read( IOStatus io_s; uint64_t elapsed = 0; + size_t alignment = file_->GetRequiredBufferAlignment(); + bool is_aligned = false; + if (scratch != nullptr) { + // Check if offset, length and buffer are aligned. + is_aligned = (offset & (alignment - 1)) == 0 && + (n & (alignment - 1)) == 0 && + (uintptr_t(scratch) & (alignment - 1)) == 0; + } + { StopWatch sw(clock_, stats_, hist_type_, (opts.io_activity != Env::IOActivity::kUnknown) @@ -106,8 +115,7 @@ IOStatus RandomAccessFileReader::Read( true /*delay_enabled*/); auto prev_perf_level = GetPerfLevel(); IOSTATS_TIMER_GUARD(read_nanos); - if (use_direct_io()) { - size_t alignment = file_->GetRequiredBufferAlignment(); + if (use_direct_io() && is_aligned == false) { size_t aligned_offset = TruncateToPageBoundary(alignment, static_cast(offset)); size_t offset_advance = static_cast(offset) - aligned_offset; @@ -182,9 +190,9 @@ IOStatus RandomAccessFileReader::Read( if (rate_limiter_->IsRateLimited(RateLimiter::OpType::kRead)) { sw.DelayStart(); } - allowed = rate_limiter_->RequestToken(n - pos, 0 /* alignment */, - rate_limiter_priority, stats_, - RateLimiter::OpType::kRead); + allowed = rate_limiter_->RequestToken( + n - pos, (use_direct_io() ? alignment : 0), rate_limiter_priority, + stats_, RateLimiter::OpType::kRead); if (rate_limiter_->IsRateLimited(RateLimiter::OpType::kRead)) { sw.DelayStop(); } diff --git a/unreleased_history/performance_improvements/avoid_memcpy_directio.md b/unreleased_history/performance_improvements/avoid_memcpy_directio.md new file mode 100644 index 000000000..d5ac0b911 --- /dev/null +++ b/unreleased_history/performance_improvements/avoid_memcpy_directio.md @@ -0,0 +1 @@ +In case of direct_io, if buffer passed by callee is already aligned, RandomAccessFileRead::Read will avoid realloacting a new buffer, reducing memcpy and use already passed aligned buffer.