改进
This commit is contained in:
@@ -22,14 +22,25 @@ endif ()
|
||||
set(Renderive_render_2D_source_dir "${CMAKE_CURRENT_LIST_DIR}/render_2D")
|
||||
append_glob_source(Renderive_render_2D_sources "${Renderive_render_2D_source_dir}")
|
||||
add_library(Renderive_render_2D STATIC ${Renderive_render_2D_sources})
|
||||
add_library(Renderive::Render2D ALIAS Renderive_render_2D)
|
||||
set_target_properties(Renderive_render_2D PROPERTIES EXPORT_NAME Render2D)
|
||||
target_include_directories(Renderive_render_2D PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
)
|
||||
target_compile_features(Renderive_render_2D PUBLIC cxx_std_20)
|
||||
target_link_libraries(Renderive_render_2D PUBLIC Renderive_Kernel blend2d::blend2d)
|
||||
if (MSVC)
|
||||
target_compile_options(Renderive_render_2D PRIVATE /utf-8)
|
||||
endif ()
|
||||
install(TARGETS Renderive_render_2D
|
||||
EXPORT RenderiveTargets
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(DIRECTORY "${Renderive_render_2D_source_dir}/"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/render_2D"
|
||||
FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp")
|
||||
if (RENDERIVE_BUILD_TESTS)
|
||||
set(Renderive_render_2D_test_dir "${CMAKE_CURRENT_LIST_DIR}/tests")
|
||||
append_glob_source(Renderive_render_2D_test_sources "${Renderive_render_2D_test_dir}")
|
||||
|
||||
@@ -74,22 +74,51 @@ struct Adaptive_Render_Partitioner {
|
||||
std::chrono::microseconds(750)),
|
||||
std::chrono::nanoseconds(frame_interval_ns / 4));
|
||||
const int previous = automatic_count_;
|
||||
const auto estimated_serial_cost = elapsed_ns * std::max(1, active_count);
|
||||
if (elapsed_ns > bottleneck_threshold && active_count < automatic_limit) {
|
||||
automatic_count_ = std::min(automatic_limit, active_count * 2);
|
||||
const auto elapsed_count = static_cast<std::uint64_t>(
|
||||
std::max<std::int64_t>(0, elapsed_ns.count()));
|
||||
const auto active = static_cast<std::uint64_t>(std::max(1, active_count));
|
||||
const auto maximum = std::numeric_limits<std::uint64_t>::max();
|
||||
const auto measured_serial_ns =
|
||||
active != 0 && elapsed_count > maximum / active
|
||||
? maximum
|
||||
: elapsed_count * active;
|
||||
if (serial_cost_ewma_ns_ == 0) {
|
||||
serial_cost_ewma_ns_ = measured_serial_ns;
|
||||
} else {
|
||||
// 75% history + 25% newest sample without overflowing uint64_t.
|
||||
serial_cost_ewma_ns_ =
|
||||
(serial_cost_ewma_ns_ / 4) * 3 + measured_serial_ns / 4;
|
||||
}
|
||||
else if (active_count > 1 &&
|
||||
estimated_serial_cost < bottleneck_threshold * 3 / 5) {
|
||||
automatic_count_ = 1;
|
||||
}
|
||||
else {
|
||||
automatic_count_ = std::clamp(active_count, 1, automatic_limit);
|
||||
const auto target_ns = static_cast<std::uint64_t>(
|
||||
std::max<std::int64_t>(1, bottleneck_threshold.count()));
|
||||
const auto required_partitions =
|
||||
serial_cost_ewma_ns_ / target_ns +
|
||||
(serial_cost_ewma_ns_ % target_ns != 0 ? 1U : 0U);
|
||||
int desired = static_cast<int>(std::min<std::uint64_t>(
|
||||
static_cast<std::uint64_t>(automatic_limit),
|
||||
std::max<std::uint64_t>(1, required_partitions)));
|
||||
// Collapse aggressively only when the measured serial work is clearly
|
||||
// below 60% of the target. Otherwise use one-step hysteresis to avoid
|
||||
// topology churn around a partition boundary.
|
||||
const auto collapse_threshold =
|
||||
(target_ns / 5) * 3 + ((target_ns % 5) * 3) / 5;
|
||||
if (measured_serial_ns < collapse_threshold && active_count > 1) {
|
||||
desired = 1;
|
||||
} else if (desired > active_count) {
|
||||
const int growth_limit = active_count <= automatic_limit / 2
|
||||
? active_count * 2
|
||||
: automatic_limit;
|
||||
desired = std::min(desired, std::max(active_count + 1, growth_limit));
|
||||
} else if (desired < active_count) {
|
||||
desired = std::max(desired, active_count - 1);
|
||||
}
|
||||
automatic_count_ = std::clamp(desired, 1, automatic_limit);
|
||||
return automatic_count_ != previous;
|
||||
}
|
||||
private:
|
||||
using Clock = std::chrono::steady_clock;
|
||||
Clock::time_point started_at_{};
|
||||
std::uint64_t serial_cost_ewma_ns_{};
|
||||
int automatic_count_{1};
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
Reference in New Issue
Block a user