parent
412e67d036
commit
750bae7b34
|
|
@ -66,7 +66,7 @@
|
|||
|
||||
|
||||
#define DEBUG_LRU false
|
||||
#define DEFAULT_ENABLE_LRU !true
|
||||
#define DEFAULT_ENABLE_LRU true
|
||||
|
||||
|
||||
TypeHandle DXGraphicsStateGuardian9::_type_handle;
|
||||
|
|
@ -123,9 +123,9 @@ DXGraphicsStateGuardian9(const FrameBufferProperties &properties) :
|
|||
Geom::GR_triangle_strip | Geom::GR_triangle_fan |
|
||||
Geom::GR_flat_first_vertex;
|
||||
|
||||
_gsg_managed_textures = !false;
|
||||
_gsg_managed_vertex_buffers = !false;
|
||||
_gsg_managed_index_buffers = !false;
|
||||
_gsg_managed_textures = false;
|
||||
_gsg_managed_vertex_buffers = false;
|
||||
_gsg_managed_index_buffers = false;
|
||||
|
||||
_enable_lru = DEFAULT_ENABLE_LRU;
|
||||
|
||||
|
|
@ -819,8 +819,8 @@ end_frame() {
|
|||
|
||||
if (false && dxgsg9_cat.is_debug())
|
||||
{
|
||||
dxgsg9_cat.debug() << "* start_priority_index " << _lru -> _m.start_priority_index << "\n";
|
||||
dxgsg9_cat.debug() << "* start_update_lru_page " << _lru -> _m.start_update_lru_page << "\n";
|
||||
dxgsg9_cat.debug() << "* start_priority_index " << _lru -> _m.start_priority_index << "\n";
|
||||
dxgsg9_cat.debug() << "* start_update_lru_page " << _lru -> _m.start_update_lru_page << "\n";
|
||||
}
|
||||
|
||||
frames = 256;
|
||||
|
|
@ -856,6 +856,24 @@ end_frame() {
|
|||
dxgsg9_cat.debug() << "* priority " << index << " pages " << _lru -> _m.lru_page_count_array [index] << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
_lru -> calculate_lru_statistics ( );
|
||||
|
||||
for (index = 0; index < _lru -> _m.maximum_page_types; index++)
|
||||
{
|
||||
PageTypeStatistics *page_type_statistics;
|
||||
|
||||
page_type_statistics = &_lru -> _m.page_type_statistics_array [index];
|
||||
dxgsg9_cat.debug() << "\n" <<
|
||||
" page type " << index <<
|
||||
" total pages " << page_type_statistics -> total_pages <<
|
||||
" in " << page_type_statistics -> total_pages_in <<
|
||||
" size " << page_type_statistics -> total_memory_in <<
|
||||
" out " << page_type_statistics -> total_pages_out <<
|
||||
" size " << page_type_statistics -> total_memory_out <<
|
||||
"\n";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1970,6 +1988,7 @@ reset() {
|
|||
{
|
||||
int maximum_memory;
|
||||
int maximum_pages;
|
||||
int maximum_page_types;
|
||||
Lru *lru;
|
||||
|
||||
maximum_memory = available_texture_memory;
|
||||
|
|
@ -1977,8 +1996,9 @@ maximum_memory = available_texture_memory;
|
|||
// TEST LRU *****
|
||||
maximum_memory = 55000000;
|
||||
maximum_pages = 20000;
|
||||
maximum_page_types = GPT_TotalPageTypes;
|
||||
|
||||
lru = new Lru (maximum_memory, maximum_pages);
|
||||
lru = new Lru (maximum_memory, maximum_pages, maximum_page_types);
|
||||
if (lru)
|
||||
{
|
||||
lru -> _m.minimum_memory = 1000000;
|
||||
|
|
|
|||
|
|
@ -37,10 +37,11 @@
|
|||
|
||||
enum GsgPageType
|
||||
{
|
||||
GPT_Error,
|
||||
GPT_Texture,
|
||||
GPT_VertexBuffer,
|
||||
GPT_IndexBuffer,
|
||||
|
||||
GPT_TotalPageTypes
|
||||
};
|
||||
|
||||
class Light;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,25 @@
|
|||
// Filename: lru.cxx
|
||||
// Created by: aignacio (12Dec05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights
|
||||
// reserved.
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
//#include "stdafx.h"
|
||||
|
||||
#define LRU_UNIT_TEST 0
|
||||
|
||||
#if LRU_UNIT_TEST
|
||||
#include "stdafx.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
|
@ -16,32 +30,35 @@
|
|||
#define HIGH_PRIORITY_SCALE 4
|
||||
#define LOW_PRIORITY_RANGE 25
|
||||
|
||||
float calculate_exponential_moving_average (float value, float weight, float average)
|
||||
{
|
||||
return ((value - average) * weight) + average;
|
||||
}
|
||||
|
||||
bool default_page_in_function (LruPage *lru_page)
|
||||
{
|
||||
char string [256];
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Lru
|
||||
// Description : Least Recently Used algorithm implementation:
|
||||
// In the Lru, each "memory page" has an associated class LruPage.
|
||||
// The Lru has a range of priorities from LPP_Highest to
|
||||
// LPP_PagedOut. Each priority has a doubly linked list of LruPages.
|
||||
// The algorithim uses an adaptive method based on the average
|
||||
// utilization of each page per frame (or time slice). The
|
||||
// average utilization is calculated with an exponetial moving
|
||||
// average. This is superior to a standard average since a standard
|
||||
// average becomes less and less adaptive the longer a page exists.
|
||||
// The average utilization is used to set the priority of each page.
|
||||
// A higher average utilization automatically raises the priority
|
||||
// of a page and a lower average utilization automatically lowers
|
||||
// the priority of a page. Therefore, pages with a higher average
|
||||
// utilization have a higher chance of being kept in memory or
|
||||
// cached and pages with a lower average utilization have a higher
|
||||
// chance of being paged out. When a page is paged in and there
|
||||
// is not enough memory available, then the lowest priority pages
|
||||
// will be paged out first until there is enough memory available.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
sprintf (string, " PAGE IN %d\n", lru_page -> _m.identifier);
|
||||
OutputDebugString (string);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool default_page_out_function (LruPage *lru_page)
|
||||
{
|
||||
char string [256];
|
||||
|
||||
sprintf (string, " PAGE OUT %d\n", lru_page -> _m.identifier);
|
||||
OutputDebugString (string);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Lru::Lru (int maximum_memory, int maximum_pages)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Lru::Lru (int maximum_memory, int maximum_pages, int maximum_page_types)
|
||||
{
|
||||
if (this)
|
||||
{
|
||||
|
|
@ -51,6 +68,7 @@ Lru::Lru (int maximum_memory, int maximum_pages)
|
|||
|
||||
this -> _m.maximum_memory = maximum_memory;
|
||||
this -> _m.maximum_pages = maximum_pages;
|
||||
this -> _m.maximum_page_types = maximum_page_types;
|
||||
this -> _m.available_memory = maximum_memory;
|
||||
this -> _m.current_frame_identifier = 1;
|
||||
this -> _m.weight = 0.20f;
|
||||
|
|
@ -83,9 +101,19 @@ Lru::Lru (int maximum_memory, int maximum_pages)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (maximum_page_types > 0)
|
||||
{
|
||||
this -> _m.page_type_statistics_array = new PageTypeStatistics [maximum_page_types];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Lru::~Lru ( )
|
||||
{
|
||||
int index;
|
||||
|
|
@ -130,8 +158,19 @@ Lru::~Lru ( )
|
|||
lru_page = next_lru_page;
|
||||
}
|
||||
}
|
||||
|
||||
if (this -> _m.page_type_statistics_array)
|
||||
{
|
||||
delete this -> _m.page_type_statistics_array;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LruPage::Constructor
|
||||
// Access: Protected
|
||||
// Description: Internal function only.
|
||||
// Call Lru::allocate_page instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LruPage::LruPage ( )
|
||||
{
|
||||
if (this)
|
||||
|
|
@ -140,11 +179,33 @@ LruPage::LruPage ( )
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LruPage::Destructor
|
||||
// Access: Protected
|
||||
// Description: Internal function only.
|
||||
// Call Lru::free_page instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LruPage::~LruPage ( )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LruPage::change_priority
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LruPage::change_priority (int delta)
|
||||
{
|
||||
this -> _m.priority_change += delta;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::register_lru_page_type
|
||||
// Access: Public
|
||||
// Description: Registers a specific type of page and its
|
||||
// required page in and out functions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Lru::register_lru_page_type (int index, LruPageTypeFunction page_in_function, LruPageTypeFunction page_out_function)
|
||||
{
|
||||
bool state;
|
||||
|
|
@ -160,11 +221,11 @@ bool Lru::register_lru_page_type (int index, LruPageTypeFunction page_in_functio
|
|||
return state;
|
||||
}
|
||||
|
||||
void LruPage::change_priority (int delta)
|
||||
{
|
||||
this -> _m.priority_change += delta;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::allocate_page
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LruPage * Lru::allocate_page (int size)
|
||||
{
|
||||
LruPage *lru_page;
|
||||
|
|
@ -180,6 +241,7 @@ LruPage * Lru::allocate_page (int size)
|
|||
this -> _m.total_lru_pages_in_free_pool--;
|
||||
|
||||
memset (&lru_page -> _m, 0, sizeof (LruPage::LruPageVariables));
|
||||
lru_page -> _m.pre_allocated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -214,6 +276,12 @@ LruPage * Lru::allocate_page (int size)
|
|||
this -> _m.total_pages++;
|
||||
this -> _m.identifier++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// ERROR: could not allocate LruPage
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -225,6 +293,11 @@ LruPage * Lru::allocate_page (int size)
|
|||
return lru_page;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::update_start_update_lru_page
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::update_start_update_lru_page (LruPage *lru_page)
|
||||
{
|
||||
if (lru_page)
|
||||
|
|
@ -252,6 +325,11 @@ void Lru::update_start_update_lru_page (LruPage *lru_page)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::free_page
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::free_page (LruPage *lru_page)
|
||||
{
|
||||
if (this -> _m.total_pages > 0)
|
||||
|
|
@ -294,6 +372,11 @@ void Lru::free_page (LruPage *lru_page)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::add_page
|
||||
// Access: Public
|
||||
// Description: Adds a page to the LRU based on the given priority.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::add_page (LruPagePriority priority, LruPage *lru_page)
|
||||
{
|
||||
if (lru_page)
|
||||
|
|
@ -315,6 +398,12 @@ void Lru::add_page (LruPagePriority priority, LruPage *lru_page)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::add_cached_page
|
||||
// Access: Public
|
||||
// Description: Adds a page that is already paged in to the LRU
|
||||
// based on the given priority.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::add_cached_page (LruPagePriority priority, LruPage *lru_page)
|
||||
{
|
||||
if (lru_page)
|
||||
|
|
@ -337,6 +426,11 @@ void Lru::add_cached_page (LruPagePriority priority, LruPage *lru_page)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::remove_page
|
||||
// Access: Public
|
||||
// Description: Removes a page from the LRU.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::remove_page (LruPage *lru_page)
|
||||
{
|
||||
if (lru_page)
|
||||
|
|
@ -379,16 +473,33 @@ void Lru::remove_page (LruPage *lru_page)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::lock_page
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::lock_page (LruPage *lru_page)
|
||||
{
|
||||
lru_page -> _m.lock = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::unlock_page
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::unlock_page (LruPage *lru_page)
|
||||
{
|
||||
lru_page -> _m.lock = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::access_page
|
||||
// Access: Public
|
||||
// Description: This must always be called before accessing or
|
||||
// using a page's memory since it pages in the page
|
||||
// if it is currently paged out.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::access_page (LruPage *lru_page)
|
||||
{
|
||||
if (lru_page)
|
||||
|
|
@ -453,12 +564,23 @@ void Lru::access_page (LruPage *lru_page)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::set_maximum_frame_bandwidth_utilization
|
||||
// Access: Public
|
||||
// Description: This must be called before accessing or using a
|
||||
// page since it pages in the page if it is paged out.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::set_maximum_frame_bandwidth_utilization (float maximum_frame_bandwidth_utilization)
|
||||
{
|
||||
this -> _m.maximum_frame_bandwidth_utilization = maximum_frame_bandwidth_utilization;
|
||||
this -> _m.frame_bandwidth_factor = (float) LPP_TotalPriorities / this -> _m.maximum_frame_bandwidth_utilization;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::begin_frame
|
||||
// Access: Public
|
||||
// Description: This must be called before each frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::begin_frame ( )
|
||||
{
|
||||
this -> _m.current_frame_identifier++;
|
||||
|
|
@ -470,6 +592,12 @@ void Lru::begin_frame ( )
|
|||
this -> _m.total_page_outs = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::update_page_priorities
|
||||
// Access: Public
|
||||
// Description: This updates the priority of a page that has a
|
||||
// change in priority.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::update_page_priorities (void)
|
||||
{
|
||||
int index;
|
||||
|
|
@ -499,8 +627,17 @@ void Lru::update_page_priorities (void)
|
|||
this -> _m.total_lru_page_priority_changes = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::update_lru_page
|
||||
// Access: Public
|
||||
// Description: This updates the page's average utilization and
|
||||
// adds it to the array of pages with changed
|
||||
// priorities if there was a change in priority.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::update_lru_page (LruPage *lru_page)
|
||||
{
|
||||
|
||||
#if LRU_UNIT_TEST
|
||||
if (false)
|
||||
{
|
||||
char string [256];
|
||||
|
|
@ -508,6 +645,7 @@ void Lru::update_lru_page (LruPage *lru_page)
|
|||
sprintf (string, " UPDATE %d\n", lru_page -> _m.identifier);
|
||||
OutputDebugString (string);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lru_page -> _m.lock == false && lru_page -> _m.in_cache)
|
||||
{
|
||||
|
|
@ -582,8 +720,18 @@ void Lru::update_lru_page (LruPage *lru_page)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::update_lru_page_old
|
||||
// Access: Public
|
||||
// Description: This updates the page's average utilization and
|
||||
// adds it to the array of pages with changed
|
||||
// priorities if there was a change in priority.
|
||||
// Old method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::update_lru_page_old (LruPage *lru_page)
|
||||
{
|
||||
|
||||
#if LRU_UNIT_TEST
|
||||
if (false)
|
||||
{
|
||||
char string [256];
|
||||
|
|
@ -591,6 +739,7 @@ void Lru::update_lru_page_old (LruPage *lru_page)
|
|||
sprintf (string, " UPDATE %d\n", lru_page -> _m.identifier);
|
||||
OutputDebugString (string);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lru_page -> _m.lock == false)
|
||||
{
|
||||
|
|
@ -707,6 +856,13 @@ void Lru::update_lru_page_old (LruPage *lru_page)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::update_entire_lru
|
||||
// Access: Public
|
||||
// Description: This updates all the pages in the Lru.
|
||||
// Lru::partial_lru_update should be called instead
|
||||
// due to performance reasons.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::update_entire_lru ( )
|
||||
{
|
||||
if (this -> _m.total_pages > 0)
|
||||
|
|
@ -733,6 +889,12 @@ void Lru::update_entire_lru ( )
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::partial_lru_update
|
||||
// Access: Public
|
||||
// Description: This only updates a number of pages up to the
|
||||
// specified maximum_updates.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::partial_lru_update (int maximum_updates)
|
||||
{
|
||||
int total_page_updates;
|
||||
|
|
@ -865,6 +1027,11 @@ void Lru::partial_lru_update (int maximum_updates)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::unlock_all_pages
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::unlock_all_pages (void)
|
||||
{
|
||||
if (this -> _m.total_pages > 0)
|
||||
|
|
@ -889,6 +1056,13 @@ void Lru::unlock_all_pages (void)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::page_out_lru
|
||||
// Access: Public
|
||||
// Description: Pages out the lowest priority pages until the
|
||||
// memory_required is satisfied. This will unlock
|
||||
// all pages if needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Lru::page_out_lru (int memory_required)
|
||||
{
|
||||
bool state;
|
||||
|
|
@ -962,6 +1136,12 @@ bool Lru::page_out_lru (int memory_required)
|
|||
return state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lru::count_priority_level_pages
|
||||
// Access: Public
|
||||
// Description: Debug function. Counts the number of pages for each
|
||||
// priority level.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lru::count_priority_level_pages (void)
|
||||
{
|
||||
int index;
|
||||
|
|
@ -987,8 +1167,100 @@ void Lru::count_priority_level_pages (void)
|
|||
}
|
||||
}
|
||||
|
||||
void Lru::calculate_lru_statistics (void)
|
||||
{
|
||||
if (this -> _m.maximum_page_types > 0)
|
||||
{
|
||||
int index;
|
||||
|
||||
memset (this -> _m.page_type_statistics_array, 0, sizeof (PageTypeStatistics) * this -> _m.maximum_page_types);
|
||||
for (index = 0; index < LPP_TotalPriorities; index++)
|
||||
{
|
||||
LruPage *lru_page;
|
||||
LruPage *next_lru_page;
|
||||
PageTypeStatistics *page_type_statistics;
|
||||
|
||||
lru_page = this -> _m.lru_page_array [index];
|
||||
while (lru_page)
|
||||
{
|
||||
volatile int type;
|
||||
|
||||
next_lru_page = lru_page -> _m.next;
|
||||
|
||||
type = lru_page -> _m.type;
|
||||
page_type_statistics = &this -> _m.page_type_statistics_array [type];
|
||||
page_type_statistics -> total_pages++;
|
||||
|
||||
if (lru_page -> _m.in_cache)
|
||||
{
|
||||
page_type_statistics -> total_pages_in++;
|
||||
page_type_statistics -> total_memory_in += lru_page -> _m.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
page_type_statistics -> total_pages_out++;
|
||||
page_type_statistics -> total_memory_out += lru_page -> _m.size;
|
||||
}
|
||||
|
||||
lru_page = next_lru_page;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: calculate_exponential_moving_average
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float calculate_exponential_moving_average (float value, float weight, float average)
|
||||
{
|
||||
return ((value - average) * weight) + average;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: default_page_in_function
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool default_page_in_function (LruPage *lru_page)
|
||||
{
|
||||
|
||||
#if LRU_UNIT_TEST
|
||||
char string [256];
|
||||
|
||||
sprintf (string, " PAGE IN %d\n", lru_page -> _m.identifier);
|
||||
OutputDebugString (string);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: default_page_out_function
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool default_page_out_function (LruPage *lru_page)
|
||||
{
|
||||
|
||||
#if LRU_UNIT_TEST
|
||||
char string [256];
|
||||
|
||||
sprintf (string, " PAGE OUT %d\n", lru_page -> _m.identifier);
|
||||
OutputDebugString (string);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if LRU_UNIT_TEST
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: test_ema
|
||||
// Access:
|
||||
// Description: Unit test function for ema.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void test_ema (void)
|
||||
{
|
||||
int index;
|
||||
|
|
@ -1016,17 +1288,24 @@ void test_ema (void)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: test_lru
|
||||
// Access:
|
||||
// Description: Unit test function for Lru.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void test_lru (void)
|
||||
{
|
||||
int maximum_memory;
|
||||
int maximum_pages;
|
||||
int maximum_page_types;
|
||||
Lru *lru;
|
||||
|
||||
test_ema ( );
|
||||
|
||||
maximum_memory = 3000000;
|
||||
maximum_pages = 3;
|
||||
lru = new Lru (maximum_memory, maximum_pages);
|
||||
maximum_page_types = 4;
|
||||
lru = new Lru (maximum_memory, maximum_pages, maximum_page_types);
|
||||
if (lru)
|
||||
{
|
||||
lru -> _m.minimum_memory = 1000000;
|
||||
|
|
@ -1121,10 +1400,10 @@ void test_lru (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
int approximate_maximum_updates;
|
||||
int maximum_updates;
|
||||
|
||||
approximate_maximum_updates = 3;
|
||||
lru -> partial_lru_update (approximate_maximum_updates);
|
||||
maximum_updates = 3;
|
||||
lru -> partial_lru_update (maximum_updates);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,20 @@
|
|||
// Filename: lru.h
|
||||
// Created by: aignacio (12Dec05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights
|
||||
// reserved.
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LRU_H
|
||||
#define LRU_H
|
||||
|
|
@ -30,6 +47,16 @@ typedef union _LruPageType
|
|||
}
|
||||
LruPageType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int total_pages;
|
||||
int total_pages_in;
|
||||
int total_pages_out;
|
||||
int total_memory_in;
|
||||
int total_memory_out;
|
||||
}
|
||||
PageTypeStatistics;
|
||||
|
||||
typedef bool (*LruPageTypeFunction) (LruPage *lru_page);
|
||||
|
||||
class LruPage
|
||||
|
|
@ -45,7 +72,7 @@ public:
|
|||
|
||||
typedef struct _LruPageVariables
|
||||
{
|
||||
LruPageType lru_page_type;
|
||||
LruPageType lru_page_type; // pointer to memory type
|
||||
|
||||
int size;
|
||||
LruPagePriority priority;
|
||||
|
|
@ -53,7 +80,7 @@ public:
|
|||
|
||||
struct
|
||||
{
|
||||
unsigned int type : 4;
|
||||
unsigned int type : 8;
|
||||
unsigned int lock : 1;
|
||||
unsigned int in_cache : 1;
|
||||
unsigned int in_memory : 1;
|
||||
|
|
@ -77,7 +104,7 @@ public:
|
|||
int total_usage;
|
||||
int update_total_usage;
|
||||
|
||||
int identifier; // this is also the number of pages created during the lifetime of the LRU
|
||||
int identifier;
|
||||
|
||||
float average_frame_utilization;
|
||||
|
||||
|
|
@ -97,7 +124,7 @@ class Lru
|
|||
{
|
||||
public:
|
||||
|
||||
Lru (int maximum_memory, int maximum_pages);
|
||||
Lru (int maximum_memory, int maximum_pages, int maximum_page_types);
|
||||
~Lru ( );
|
||||
|
||||
bool register_lru_page_type (int index, LruPageTypeFunction page_in_function, LruPageTypeFunction page_out_function);
|
||||
|
|
@ -130,6 +157,8 @@ public:
|
|||
|
||||
void count_priority_level_pages (void);
|
||||
|
||||
void calculate_lru_statistics (void);
|
||||
|
||||
private:
|
||||
bool page_out_lru (int memory_required);
|
||||
void update_page_priorities (void);
|
||||
|
|
@ -148,6 +177,7 @@ public:
|
|||
|
||||
int maximum_memory;
|
||||
int minimum_memory; // target amount of memory to keep free if possible
|
||||
int maximum_page_types;
|
||||
|
||||
int total_lifetime_page_ins;
|
||||
int total_lifetime_page_outs;
|
||||
|
|
@ -164,12 +194,11 @@ public:
|
|||
int maximum_page_updates_per_frame; // unused pages
|
||||
|
||||
int start_priority_index;
|
||||
int update_overflow;
|
||||
LruPage *start_update_lru_page;
|
||||
|
||||
int identifier;
|
||||
int identifier; // this is also the number of pages created during the lifetime of the LRU
|
||||
|
||||
float weight;
|
||||
float weight; // used for exponential moving average
|
||||
float maximum_frame_bandwidth_utilization;
|
||||
|
||||
float frame_bandwidth_factor;
|
||||
|
|
@ -189,6 +218,8 @@ public:
|
|||
int total_lru_pages_in_free_pool;
|
||||
LruPage **lru_page_pool;
|
||||
LruPage **lru_page_free_pool;
|
||||
|
||||
PageTypeStatistics *page_type_statistics_array;
|
||||
}
|
||||
LruVariables;
|
||||
|
||||
|
|
@ -204,5 +235,4 @@ bool default_page_out_function (LruPage *lru_page);
|
|||
void test_ema (void);
|
||||
void test_lru (void);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue