Skip to content

Commit

Permalink
Added the performance counter for post_query and also a time budget f…
Browse files Browse the repository at this point in the history
…or that, but disabled the budgeting for now.
  • Loading branch information
JarkkoPar committed Dec 14, 2023
1 parent ce8a390 commit e4d44df
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 33 deletions.
122 changes: 94 additions & 28 deletions src/NodeQuerySystem/UtilityAINodeQuerySystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,24 @@ using namespace godot;


UtilityAINodeQuerySystem::UtilityAINodeQuerySystem() {
_time_budget_per_frame = 1000;
_current_high_priority_query_index = 0;
_current_regular_query_index = 0;

_time_allocation_pct_to_high_priority_queries = 0.8f;
_time_budget_per_frame_high_priority_queries = (uint64_t)(_time_allocation_pct_to_high_priority_queries * ((float)_time_budget_per_frame));
_time_budget_per_frame_regular_queries = _time_budget_per_frame - _time_budget_per_frame_high_priority_queries;

_run_queries_time_budget_per_frame = 1000;
_run_queries_time_budget_per_frame_high_priority_queries = (uint64_t)(_time_allocation_pct_to_high_priority_queries * ((float)_run_queries_time_budget_per_frame));
_run_queries_time_budget_per_frame_regular_queries = _run_queries_time_budget_per_frame - _run_queries_time_budget_per_frame_high_priority_queries;

_post_query_time_budget_per_frame = 500;
_post_query_time_budget_per_frame_high_priority_queries = (uint64_t)(_time_allocation_pct_to_high_priority_queries * (double)_post_query_time_budget_per_frame);
_post_query_time_budget_per_frame_regular_queries = _post_query_time_budget_per_frame - _post_query_time_budget_per_frame_high_priority_queries;

_post_high_priority_queries_time_elapsed_usec = 0;
_post_regular_queries_time_elapsed_usec = 0;
_run_queries_time_elapsed_usec = 0;
_current_post_high_priority_queries_time_elapsed_usec = 0;
_current_post_regular_queries_time_elapsed_usec = 0;

_is_performance_counter_initialized = false;
}
Expand All @@ -24,10 +35,14 @@ UtilityAINodeQuerySystem::~UtilityAINodeQuerySystem() {
}

void UtilityAINodeQuerySystem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_time_budget_per_frame", "time_budget_per_frame"), &UtilityAINodeQuerySystem::set_time_budget_per_frame);
ClassDB::bind_method(D_METHOD("get_time_budget_per_frame"), &UtilityAINodeQuerySystem::get_time_budget_per_frame);
ADD_PROPERTY(PropertyInfo(Variant::INT, "time_budget_per_frame", PROPERTY_HINT_RANGE, "1,10000,or_greater"), "set_time_budget_per_frame","get_time_budget_per_frame");

ClassDB::bind_method(D_METHOD("set_run_queries_time_budget_per_frame", "run_queries_time_budget_per_frame"), &UtilityAINodeQuerySystem::set_run_queries_time_budget_per_frame);
ClassDB::bind_method(D_METHOD("get_run_queries_time_budget_per_frame"), &UtilityAINodeQuerySystem::get_run_queries_time_budget_per_frame);
ADD_PROPERTY(PropertyInfo(Variant::INT, "run_queries_time_budget_per_frame", PROPERTY_HINT_RANGE, "1,10000,or_greater"), "set_run_queries_time_budget_per_frame","get_run_queries_time_budget_per_frame");

ClassDB::bind_method(D_METHOD("set_post_query_time_budget_per_frame", "post_query_time_budget_per_frame"), &UtilityAINodeQuerySystem::set_post_query_time_budget_per_frame);
ClassDB::bind_method(D_METHOD("get_post_query_time_budget_per_frame"), &UtilityAINodeQuerySystem::get_post_query_time_budget_per_frame);
ADD_PROPERTY(PropertyInfo(Variant::INT, "post_query_time_budget_per_frame", PROPERTY_HINT_RANGE, "1,10000,or_greater"), "set_post_query_time_budget_per_frame","get_post_query_time_budget_per_frame");

ClassDB::bind_method(D_METHOD("set_time_allocation_pct_to_high_priority_queries", "time_allocation_pct_to_high_priority_queries"), &UtilityAINodeQuerySystem::set_time_allocation_pct_to_high_priority_queries);
ClassDB::bind_method(D_METHOD("get_time_allocation_pct_to_high_priority_queries"), &UtilityAINodeQuerySystem::get_time_allocation_pct_to_high_priority_queries);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_allocation_pct_to_high_priority_queries", PROPERTY_HINT_RANGE, "0.0,1.0"), "set_time_allocation_pct_to_high_priority_queries","get_time_allocation_pct_to_high_priority_queries");
Expand All @@ -37,25 +52,45 @@ void UtilityAINodeQuerySystem::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_queries"), &UtilityAINodeQuerySystem::clear_queries);
ClassDB::bind_method(D_METHOD("initialize_performance_counters"), &UtilityAINodeQuerySystem::initialize_performance_counters);
ClassDB::bind_method(D_METHOD("get_run_queries_time_elapsed_usec"), &UtilityAINodeQuerySystem::get_run_queries_time_elapsed_usec );
ClassDB::bind_method(D_METHOD("get_post_queries_time_elapsed_usec"), &UtilityAINodeQuerySystem::get_post_queries_time_elapsed_usec );

}


// Getters and setters.

void UtilityAINodeQuerySystem::set_time_budget_per_frame( uint64_t time_budget_per_frame ) {
_time_budget_per_frame = time_budget_per_frame;
void UtilityAINodeQuerySystem::set_run_queries_time_budget_per_frame( uint64_t run_queries_time_budget_per_frame ) {
_run_queries_time_budget_per_frame = run_queries_time_budget_per_frame;
_run_queries_time_budget_per_frame_high_priority_queries = (uint64_t)(_time_allocation_pct_to_high_priority_queries * (double)_run_queries_time_budget_per_frame);
}


uint64_t UtilityAINodeQuerySystem::get_time_budget_per_frame() const {
return _time_budget_per_frame;
uint64_t UtilityAINodeQuerySystem::get_run_queries_time_budget_per_frame() const {
return _run_queries_time_budget_per_frame;
}



void UtilityAINodeQuerySystem::set_post_query_time_budget_per_frame( uint64_t post_query_time_budget_per_frame ) {
_post_query_time_budget_per_frame = post_query_time_budget_per_frame;
_post_query_time_budget_per_frame_high_priority_queries = (uint64_t)(_time_allocation_pct_to_high_priority_queries * (double)_post_query_time_budget_per_frame);
_post_query_time_budget_per_frame_regular_queries = _post_query_time_budget_per_frame - _post_query_time_budget_per_frame_high_priority_queries;
}


uint64_t UtilityAINodeQuerySystem::get_post_query_time_budget_per_frame() const {
return _post_query_time_budget_per_frame;
}


void UtilityAINodeQuerySystem::set_time_allocation_pct_to_high_priority_queries( float time_allocation_pct_to_high_priority_queries ) {
_time_allocation_pct_to_high_priority_queries = time_allocation_pct_to_high_priority_queries;
_time_budget_per_frame_high_priority_queries = (uint64_t)(_time_allocation_pct_to_high_priority_queries * (float)_time_budget_per_frame);
_time_budget_per_frame_regular_queries = _time_budget_per_frame - _time_budget_per_frame_high_priority_queries;

_run_queries_time_budget_per_frame_high_priority_queries = (uint64_t)(_time_allocation_pct_to_high_priority_queries * (double)_run_queries_time_budget_per_frame);
_run_queries_time_budget_per_frame_regular_queries = _run_queries_time_budget_per_frame - _run_queries_time_budget_per_frame_high_priority_queries;

_post_query_time_budget_per_frame_high_priority_queries = (uint64_t)(_time_allocation_pct_to_high_priority_queries * (double)_post_query_time_budget_per_frame);
_post_query_time_budget_per_frame_regular_queries = _post_query_time_budget_per_frame - _post_query_time_budget_per_frame_high_priority_queries;
}


Expand All @@ -67,21 +102,37 @@ int UtilityAINodeQuerySystem::get_run_queries_time_elapsed_usec() const {
return _run_queries_time_elapsed_usec;
}

int UtilityAINodeQuerySystem::get_post_queries_time_elapsed_usec() const {
return (_post_high_priority_queries_time_elapsed_usec + _post_regular_queries_time_elapsed_usec);
}



// Handling methods.

void UtilityAINodeQuerySystem::initialize_performance_counters() {
if( _is_performance_counter_initialized ) return;
Performance* perf = godot::Performance::get_singleton();
if( perf == nullptr ) return;
perf->add_custom_monitor("NodeQuerySystem/Run_Queries_Time_usec", Callable(this, "get_run_queries_time_elapsed_usec"));
perf->add_custom_monitor("NodeQuerySystem/Run queries time usec", Callable(this, "get_run_queries_time_elapsed_usec"));
perf->add_custom_monitor("NodeQuerySystem/Post queries time usec", Callable(this, "get_post_queries_time_elapsed_usec"));
_is_performance_counter_initialized = true;
}


void UtilityAINodeQuerySystem::run_queries() {
uint64_t method_start_time_usec = godot::Time::get_singleton()->get_ticks_usec();
uint64_t frame_time_left = _time_budget_per_frame;

// Clear the post queries time measurement.
_post_high_priority_queries_time_elapsed_usec = _current_post_high_priority_queries_time_elapsed_usec;
_current_post_high_priority_queries_time_elapsed_usec = 0;

_post_regular_queries_time_elapsed_usec = _current_post_regular_queries_time_elapsed_usec;
_current_post_regular_queries_time_elapsed_usec = 0;


// Then continue with the update.
uint64_t frame_time_left = _run_queries_time_budget_per_frame;
if( _high_priority_queries.size() == 0 && _regular_queries.size() == 0 ) {
_run_queries_time_elapsed_usec = godot::Time::get_singleton()->get_ticks_usec() - method_start_time_usec;
return;
Expand Down Expand Up @@ -111,7 +162,7 @@ void UtilityAINodeQuerySystem::run_queries() {

++_current_high_priority_query_index;
uint64_t time_used = godot::Time::get_singleton()->get_ticks_usec() - method_start_time_usec;
if( time_used >= _time_budget_per_frame_high_priority_queries ) {
if( time_used >= _run_queries_time_budget_per_frame_high_priority_queries ) {
break;
}
}
Expand Down Expand Up @@ -174,30 +225,45 @@ void UtilityAINodeQuerySystem::run_queries() {


int UtilityAINodeQuerySystem::post_query( UtilityAINQSSearchSpaces* search_space, bool is_high_priority ) {
if( search_space == nullptr ) {
return -1;
}
uint64_t method_start_time_usec = godot::Time::get_singleton()->get_ticks_usec();

if( is_high_priority ) {
if( _high_priority_queries.has( search_space ) ){
if( search_space == nullptr ){ //|| _post_high_priority_queries_time_elapsed_usec >= _post_query_time_budget_per_frame_high_priority_queries ) {
_current_post_high_priority_queries_time_elapsed_usec += (godot::Time::get_singleton()->get_ticks_usec() - method_start_time_usec);
return -1;
}
search_space->start_query();
_high_priority_queries.push_back(search_space);
return 1;
} else {
if( _regular_queries.has( search_space ) ){

if( _high_priority_queries.has( search_space ) ){
_current_post_high_priority_queries_time_elapsed_usec += (godot::Time::get_singleton()->get_ticks_usec() - method_start_time_usec);
return -1;
}
search_space->start_query();
_regular_queries.push_back(search_space);
_high_priority_queries.push_back(search_space);
_current_post_high_priority_queries_time_elapsed_usec += (godot::Time::get_singleton()->get_ticks_usec() - method_start_time_usec);
return 1;
}

if( search_space == nullptr ) { //} || _post_regular_queries_time_elapsed_usec >= _post_query_time_budget_per_frame_regular_queries ) {
_current_post_regular_queries_time_elapsed_usec += (godot::Time::get_singleton()->get_ticks_usec() - method_start_time_usec);
return -1;
}


// Regular priority.
if( _regular_queries.has( search_space ) ){
_current_post_regular_queries_time_elapsed_usec += (godot::Time::get_singleton()->get_ticks_usec() - method_start_time_usec);
return -1;
}
search_space->start_query();
_regular_queries.push_back(search_space);
_current_post_regular_queries_time_elapsed_usec += (godot::Time::get_singleton()->get_ticks_usec() - method_start_time_usec);
return 1;

return -1;
}


void UtilityAINodeQuerySystem::clear_queries() {
_high_priority_queries.clear();
_regular_queries.clear();
}
}

21 changes: 16 additions & 5 deletions src/NodeQuerySystem/UtilityAINodeQuerySystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,19 @@ class UtilityAINodeQuerySystem : public UtilityAI {
godot::TypedArray<UtilityAINQSSearchSpaces> _regular_queries;
int _current_high_priority_query_index;
int _current_regular_query_index;
uint64_t _time_budget_per_frame;
uint64_t _time_budget_per_frame_high_priority_queries;
uint64_t _time_budget_per_frame_regular_queries;
uint64_t _post_query_time_budget_per_frame;
uint64_t _run_queries_time_budget_per_frame;
uint64_t _run_queries_time_budget_per_frame_high_priority_queries;
uint64_t _run_queries_time_budget_per_frame_regular_queries;
float _time_allocation_pct_to_high_priority_queries;
bool _is_performance_counter_initialized;
uint64_t _run_queries_time_elapsed_usec;
uint64_t _current_post_high_priority_queries_time_elapsed_usec;
uint64_t _current_post_regular_queries_time_elapsed_usec;
uint64_t _post_high_priority_queries_time_elapsed_usec;
uint64_t _post_regular_queries_time_elapsed_usec;
uint64_t _post_query_time_budget_per_frame_high_priority_queries;
uint64_t _post_query_time_budget_per_frame_regular_queries;
protected:
static void _bind_methods();

Expand All @@ -35,13 +42,17 @@ class UtilityAINodeQuerySystem : public UtilityAI {

// Getters and setters.

void set_time_budget_per_frame( uint64_t time_budget_per_frame );
uint64_t get_time_budget_per_frame() const;
void set_post_query_time_budget_per_frame( uint64_t post_query_time_budget_per_frame );
uint64_t get_post_query_time_budget_per_frame() const;

void set_run_queries_time_budget_per_frame( uint64_t time_budget_per_frame );
uint64_t get_run_queries_time_budget_per_frame() const;

void set_time_allocation_pct_to_high_priority_queries( float time_allocation_pct_to_high_priority_queries );
float get_time_allocation_pct_to_high_priority_queries() const;

int get_run_queries_time_elapsed_usec() const;
int get_post_queries_time_elapsed_usec() const;

// Handling methods.
void initialize_performance_counters();
Expand Down

0 comments on commit e4d44df

Please sign in to comment.