[RELz]Oblivion Stutter Remover

Post » Thu May 12, 2011 6:44 pm

This is thread #8.
Thread #7 is http://www.gamesas.com/bgsforums/index.php?showtopic=1068356
Thread #6 is http://www.gamesas.com/bgsforums/index.php?showtopic=1038949
Thread #5 is http://www.gamesas.com/bgsforums/index.php?showtopic=1029432
Thread #4 is http://www.gamesas.com/bgsforums/index.php?showtopic=987905
Thread #3 is http://www.gamesas.com/bgsforums/index.php?showtopic=979841
Thread #2 is http://www.gamesas.com/bgsforums/index.php?showtopic=968943
Thread #1 is http://www.gamesas.com/bgsforums/index.php?showtopic=965106

Version 4.1 is available from tesnexus here: http://tesnexus.com/downloads/file.php?id=23208
The latest WIP version is available from my ftp server, currently at: ftp://71.115.222.171/sr_Oblivion_Stutter_Remover.dll

Current readme for OSR version 4:
Oblivion Stutter Remover
version 4.1.0
by SkyRanger-1

Forum thread: http://www.gamesas.com/bgsforums/index.php?showtopic=1068356
TESnexus page: http://tesnexus.com/downloads/file.php?id=23208

This is an OBSE plugin, and it will not work without a recent version of OBSE.


====================================
0. Contents:
====================================

0. Contents
1. Overview
2. Installing
3. Uninstalling
4. Common Settings Changes
5. All Settings
6. Version History
7. How This Works
8. Credits


====================================
1. Overview:
====================================

This plugin makes Oblivion not "stutter" as much, and generally feel smoother or perform better. It prevents or mitigates a number of issues related to stuttering and framerates, and can reduce the frequency of stutter related crashes. For more detail, see Section 7: How This Works.

Note however that this is not a substitute for Silent Feet / PyFFI / Oblivion Crash Prevention System / etc. For instance if you get major stuttering because of sound driver or sound hardware issues, this might help but Silent Feet would be likely to help more.

This is compatible with everything except earlier versions of itself. The only caveat is that Streamline (and other mods that monitor FPS) will not be able to accurately measure FPSes outside of the target range set by this plugin (10 to 30 by default). In fact, even FPSes that merely come close to OSR targets may be difficult to measure. In general, there should be at least a 10% margin between any FPS that you want a mod like Streamline to be able to measure and the OSR target. i.e. If OSR FPS targets are 10 to 30, then Streamline FPS min should be at least 11 and Streamline FPS max should be at most 27.


====================================
2. Installing:
====================================

The installation process is:

1.A. If the version of OSR you are installing came as a .zip file, simply drag the "Data" folder from the zip to your Oblivion folder.

1.B. If the version of OSR you are installing did NOT come as a .zip file then you need to place the file sr_Oblivion_Stutter_Remover.dll in to your Oblivion\Data\obse\plugins folder. If you don't have such a folder, create it. If you had an older version of OSR installed, delete its ini file (Data\obse\plugins\sr_Oblivion_Stutter_Remover.ini). If there is no existing OSR ini file then OSR will generate a new ini file with settings appropriate for your version the next time you run Oblivion.

2. [Optional] Customize your OSR settings by adjusting the OSR ini file. For settings you might want to adjust, see section 4. The OSR ini file is Data\obse\plugins\sr_Oblivion_Stutter_Remover.ini


====================================
3. Uninstalling:
====================================

Simply delete the sr_Oblivion_Stutter_Remover.dll file from your Data\obse\plugins folder.
Moving that file to another directory would also be sufficient.


====================================
4. Common Settings Changes
====================================

In general, OSR attempts to have decent default settings so that users are not required to monkey with them. However, there are a few settings where the default values might not be appropriate for you, either because the default values do not match your tastes or because OSR is makes incorrect assumptions about your computer.

OSR keeps its settings in the file Data\obse\plugins\sr_Oblivion_Stutter_Remover.ini
If that file is not present, simply launch Oblivion with OSR installed and OSR will generate a new one with default settings for your version of OSR. If you have screwed something up in your settings or otherwise want to revert to default settings, simply delete this ini file and launch Oblivion.

You can find general information about settings in section 5, as well as more complete information on each individual setting.

The settings you are most likely to want to change are:

Master\bReplaceHeap: (defaults to 0, consider changing to 1)
This is still off by default because some people experience instability with it. Turning on heap replacement does improvement performance though. The amount it improves performance by depends upon how much multithreading your copy of Oblivion tries to do - if it tries to do a lot of multithreading then this setting can produce really huge improvements. This also helps with some serious performance issues that arise in longer game sessions when playing a heavily modded game on Oblivion on Windows XP. If you have trouble with Master\bReplaceHeap turned on then you might try different heap algorithms by changing Heap\iHeapAlgorithm, which should usually be either 1, 5, or 3.

FPS_Management\MaximumFPS: (defaults to 30, consider changing to 0 or other values)
Some people don't want their framerate limited at all. You can turn off FPS limiting by setting this to 0. Also, if your screen refresh rate when playing Oblivion is not 60 Hertz, you might try changing this to your screen refresh rate, or half your screen refresh rate, or one third your screen refresh rate. This setting will have no effect if Master\bManageFPS is changed to 0.

Hashtables\bAllowDynamicResizing: (defaults to 0, consider changing to 1)
Turning this on can improve general performance / FPS significantly on heavily modded games. Unfortunately, it may cause race conditions and general mayhem, particularly when scripts using certain OBSE commands are running every frame. I've attempted to reduce the chance of problems to near zero, but... it may require more work yet. Meantime this feature defaults to disabled. This setting will have no effect if Master\bHookHashtables is changed to 0.

Critical Section Suppression: (special)
By default OSR suppresses one particular critical section that Oblivion seems to work better without. There is another related critical section which some users seem to be able to suppress without causing problems, but other users experience CTDs on interior->exterior transitions or other problems when its suppressed. That one only produces a small improvement to stuttering, so I don't normally recommend suppressing it, but you can if you want to. To suppress it, find the line that says "CallerAddress = 0x70172A" in your ini file and add a new line right after it that says "Mode = 5". Note that case is important there... it should be "Mode" and not "mode". This setting will have no effect if Master\bHookCriticalSections or CriticalSections\bUseOverrides are set to 0.


====================================
5. All Settings
====================================

OSR keeps its settings in the file Data\obse\plugins\sr_Oblivion_Stutter_Remover.ini
If that file is not present, simply launch Oblivion with OSR installed and OSR will generate a new one with default settings for your version of OSR. If you have screwed something up in your settings or otherwise want to revert to default settings, simply delete this ini file and launch Oblivion.

Note that the format of OSR ini files changes between major versions of OSR - you should not use an OSR version 3 ini file with OSR version 4, etc. In OSR4, the ini file is organized in to sections like "SectionName { SettingName = Value }". A specific setting may be refered to as SectionName\SettingName to distinguish it from other settings with the same name in different sections. In general settings with names that begin with an "i" are integer values (ie a number with no decimal point), setting with names that begin with a "b" are boolean values (ie either 0 or 1), and settings that begin with an "f" are numbers which may have decimal points in them (ie 3.14). Some settings do not begin with one of those letters, in which case it may not be clear what the proper type of values are.

These are the settings and their current default values (may not be 100% up to date):

Section: Master{}
This section contains an option to disable each major subsystem of OSR, plus a few settings for things that don't belong to any particular subsystem of OSR.

Master\bManageFPS (default: 1)
Setting this to 0 will disable all FPS management stuff, making every setting in the FPS_Management section meaningless.

Master\bHookCriticalSections (default: 1)
Setting this to 0 will disable all Critical Section stuff, making every setting in the CriticalSections section meaningless.

Master\bHookHashtables (default: 1)
Setting this to 0 will disable all Hashtable stuff, making every setting in the CriticalSections section meaningless.

Master\bReplaceHeap (default: 0)
Setting this to 1 will enable heap replacement, making the settings in the Heap section meaningful.

Master\bLogToConsole (default: 0)
OSR logs various bits of information to its log file. Changing this setting to 1 will cause OSR to also print that information to the console.
The log file is sr_Oblivion_Stutter_Remover.log in the Oblivion directory. It is created or overwritten each time Oblivion runs with OSR installed.

Master\bFix64Hertz (default: 1)
Setting this to 1 fixes a problem in Oblivion that causes "microstutter". This problem is sometimes known as the "64 Hertz issue". Specifically the issue is that Oblivion game logic timing normally occurs at a resolution of 1/64th of a second, and screen refresh rates normally permit Oblivion to draw 60 frames per second when vsync limited. This combination creates a kind of beat frequency when the framerate is maxed out in which 4 frames each second have twice the amount of game time pass as the other 56 frames. The fix that OSR applies forces Oblivion to use time at a resolution of 1/1000th of a second instead of 1/64th of a second.

Master\bFlushLog (default: 1)
This tells OSR to write any log messages to its file immediately instead of buffering them in memory. It can reduce performance slightly due to larger number of disk accesses, but it makes it more likely that any messsages pertaining to problems that occur shortly before a crash will successfully get written to the log file.

Master\iSchedulingResolution (default: 1)
OSR will request that the Windows scheduler run at a resolution of this many milliseconds. With this set at 1, OSR and Oblivion generally work better. This can slightly reduce the battery life of laptops however.

Section: FPS_Management{}
This section contains settings that adjust how OSR manages your framerate and the flow of game time.

FPS_Management\bAllowSlowMotion (default: 1)
Setting this to 0 will prevent OSR from attempting to override the normal flow of game time. In the past bugs have arison from OSR doing so (most infamously, the nearby-NPCs-drop-dead-on-cell-transitions bug), but these are believed to be fixed now. Just in case you suspect there might be an issue though, you can forcibly disable all OSR game time adjustments with this setting. Despite the name, setting this to 0 will also prevent OSR from fast-forwarding game time, though OSR only tries to do that under very rare combinations of settings and circumstances.

FPS_Management\MaximumFPS (default: 30)
This is a maximum FPS that OSR will not permit Oblivion to exceed. I generally set this to a framerate high enough that I won't really care much about any extra frames per second. Note that OSR does not really deal with "frames per second" here, it converts that value to a milliseconds-per-frame number instead, and considers each frame individually. If a frame would be finished too quickly then OSR will cause Oblivions main thread to go to sleep until the correct number of milliseconds have passed. Putting Oblivions main thread to sleep can free up resources for use by Oblivions background threads or for other programs that may be running in the background. If nothing wants to use the extra resources then your CPU and/or GPU will run colder and use less electricity.

FPS_Management\MinimumFPS (default: 10)
This is a minimum FPS that OSR will not permit Oblivion to go under. However, instead of dealing with real seconds, this deals with seconds of game time. So you can still have an FPS of 1 if your computer is really slow, but this would slow down game time to 10% of normal so that there will always be at least 10 frames per second of game time. All the numbers there were just for example, based upon a real FPS of 1 and a MinimumFPS setting of 10 (the default value). Also note that like MaximumFPS this actually works on a single-frame basis dealing with millisecond per frame instead of frames per second.
I generally set this to the lower FPS that I find remotely playable. The big purpose of this setting is to prevent Oblivions game logic from going berserk when the FPS gets too low. Issues that this prevents include fights that are impossible because enemies can run circles around you between frames, screwed up controls because Oblivion thinks that the attack key is down for an entire frame or not down for an entire frame which may cause a power attack to occur when an attack was intended, and lots of other similar issues.

FPS_Management\iSmoothFrames (default: 0)
If this is set to 0, the "smoothing" logic doesn't do anything. To turn on the smoothing logic try setting this to 2. However, reports suggest that the smoothing logic isn't really worth much of anything. The smoothing logic is intended to prevent a variety of issues that arise from stutters and other rapid changes in framerates. The smoothing logic will have no effect if bAllowSlowMotion is 0.

FPS_Management\iSmoothMode (default: 0)
This should be 0, 1, 2, or 3. If it's 0 or 1 then it will enable some extra logic that tries to filter stutter events out of the flow of time. That logic can end up with the total amount of gametime that passes not being quite equal to the amount of real time that passes if there was a very sudden drop in FPS. If it's 2 or 3 then that extra bit of logic is disabled. The difference betteen 0/2 and 1/3 is a very subtle issue of which frames get time redistributed between them how.

FPS_Management\iSleepExtra (default: 2)
OSR will force Oblivion to sleep for this many milliseconds every second. This can help free up resources for background threads or other processes, or reduce the temperature & power consumption of computer components slightly. The main benefit is that if some background thread is struggling to get a particular resource that the main thread is hogging, this can give it a chance to get ahold of that resource once in a while.
If this is set to -1 then the OSR FPS management code will never put Oblivion to sleep - if the FPS would otherwise exceed MaximumFPS then OSR will waste time in an idle loop. That mode is not recommended as is provided for testing purposes only.

FPS_Management\bFPSConsoleSPAM (default: 0)
This will cause OSR to log the amount of time it takes to complete each frame. It will do so once per frame, creating an enormous amount of logged times.

FPS_Management\iSchedulingParanoia (default: 1)
This setting is in units of milliseconds. It determines how paranoid the MaximumFPS code is about the scheduler. If the value is high, then the MaximumFPS code will never sleep, instead wasting time in idle loops. If the value is 0, then the MaximumFPS code will trust the scheduler to resume the main threads execution at exactly the requested time. Generally I compromise at 1 for a modicrum of paranoia about the scheduler but still allowing much of the spare time to be put to constructive use.

FPS_Management\iHardMaxFrametime (default: 200)
This is in units of milliseconds. It's been found that when my time flow adjusting code puts in a time that's too large at the wrong time, strange things happen. Bad things. Like, nearby NPCs randomly dropping dead. This setting prevents that, by setting an absolute maximum to the number of milliseconds OSR permits to pass at once in the normal course of things. Normally you'll hit MinimumFPS before you hit this limit, but MinimumFPS gets waived under some circumstances to prevent side effects like lip movements desynching with voices, so this acts a sort of 2nd level of MinimumFPS, the I-really-mean-it minimum FPS. Setting this too low can cause things like lip movements desynching in conversations, setting it too high can permit bugs like NPCs-dropping-dead-randomly. I set 200 as a compromise - it should not cause lips to desynch unless your framerate drops to less than 5 in a conversation. And if you are playing Oblivion at a framerate of less than 5 then you need serious help.

Section: CriticalSections{}
This section deals with all the changes that OSR makes to Oblivions CRITICAL_SECTIONs. Want to know about CRITICAL_SECTION objects? Oblivion uses them to prevent its various threads from accidentally killing each other. Microsoft provides the code for them. Oblivion uses slightly different versions of them depending upon which version of Windows it runs on. You can read more about them on MSDN.

CriticalSections\bEnableProfiling (default: 0)
If set to 1 then OSR will record information about the timing / performance of critical section operations in Oblivion. Doing so cause a small but significant penalty to performance. OSR will record the information in its log file. This can potentially produce useful information about why your Oblivion is stuttering or running slowly. That info might be used to adjust the Overrides section of the OSR ini file or something.

CriticalSections\bEnableMessages (default: 0)
If set to 1 then OSR will record information about some timing / performance events of critical sections. There is very little performance cost to doing so, but it can clutter up the log file making it harder to find non-critical-section information in there.

CriticalSections\bUseOverrides (default: 1)
If this is set to 1 then OSR will use the settings in the Overrides section of the ini to determine what is should do to specific critical sections.

CriticalSections\iDefaultMode (default: 2)
This determines what OSR does to critical sections that don't have a Mode entry for them in the Overrides list.
1: it leaves that critical section at aproximately normal behavior.
2: it adjusts that critical section to improve fairness at the cost of throughput. This can prevent one thread from hogging a critical section too much, but can net rate at which operations can be done with that critical section.
3: an attempted compromise between fairness and throughput in which it usually optimizes for throughput but once in a while switches behavior to optimize for fairness.
5: that critical section is suppressed. Suppressing critical sections generally causes Oblivion to crash, but also generally improves performance. Certain critical sections may be affected differently though.
6: that the main thread gets priority for that critical section.
7: that background threads get priority for that critical section.

CriticalSections\iDefaultSpin (default: 1000)
This effects how long a thread will keep trying to enter a critical section before asking the scheduler to put it to sleep until that critical section becomes available. In theory a value that is too small will result in too much scheduler overhead, while a value that is too large will result in wasted CPU cycles. 1000 is actually a kinda small value I think. The ideal value may increase with the number of cores / hardware threads you have.

CriticalSections\iStutterLevel (default: 4)
This parameter effecst how often critical section mode 2 switches behavior. See iDefaultMode for more about critical section mode 2. A smaller number means frequent switches, a larger number means infrequent switches. The ideal value should probably be somewhere in the range of 3 to 6.

Section: Heap{}
The vanilla Oblivion heap is really really bad at dealing with multithreaded workloads. It also has a tendency to suddenly and dramatically slow down after long game sessions in heavily modded games. OSR can replace the vanilla Oblivion heap with a different heap to fix these issues.

Heap\iHeapAlgorithm (default: 5)
This chooses which heap OSR will force Oblivion to use.
1: FastMM4 heap. This requires BorlndMM.dll to be present in Data\obse\plugis\ComponentDLLs, otherwise it will prevent Oblivion from starting up. This heap is fast and flexible.
2: Windows standard heap. OS dependant. A really bad idea on XP, but okay on Vista and Windows 7.
3: A heap I wrote titled SimpleHeap1. It's reasonably fast.
4: Don't use this one.
5: A heap I wrote titled ThreadHeap2. It's reasonably fast.

Heap\bEnableProfiling (default: 0)
If this is set to 1 then OSR will measure the performance of the heap it provides and record it to the log. This can't measure the performance of the vanilla heap, only the performance of OSR-provided heaps.

Heap\iHeapSize (default: 450)
This only effects heap algorithms #3 and #5 (see iHeapAlgorithm above) - the other heaps choose their own size and dynamically resize themselves. It is the number of megabytes that the heap reserves for dynamically allocated objects in Oblivion.

Heap\bEnableMessages (default: 0)
If this is set to 1 then the OSR heap code may occaisonally record a little information to the log.

Section: Hashtables{}
Oblivion includes a bunch of hashtables for looking up all sorts of things. They use a generally horrid hashtable implementation, but the real problem is they never resize their hashtables and the default sizes they use are targetted at an unmodded game and often rather small even for that. When a hashtable gets overful, performance drops. If a hashtable is underful then a tiny bit of memory may be wasted, and cache coherency may drop. Unfortunately, much of the hashtable code is inlined all over the place, and OBSE makes various assumptions about the hashtables as well, and its not at all clear to me what the relevant threading model is supposed to be, so changing them safely is quite difficult. Still, I have some hashtable hooks, and they're gradually getting better.

Hashtables\bAllowDynamicResizing (default: 0)
If this is set to 1 then OSR will increase the size of hashtables once they get overful. The act of resizing them is fraught with problems however - it can cause crashes or glitches, and the methods I use to prevent it from doing so can cause small performance stutters or other crashes or glitches. Still, at this point I think it might be working kinda decently.

Hashtables\bUseOverrides (default: 0)
Currently there are no hashtable overrides, and the syntax for specifying them is awkward and has the potential to silently fail and do something else instead if you enter the wrong value. This will get fixed up eventually though to allow ini-file-specified hooks in to the initialization of the most important hashtables to make them start out at a decent size instead of needing to be resized later.

Hashtables\bEnableProfiling (default: 0)
This will monitor hashtables and log information about how full they are and how much they get accessed.

Hashtables\bEnableMessages (default: 0)
If this is 1 then the hashtables code may occasionally log messages about what it is doing.

Hashtables\iHashtableResizeScale1 (default: 2)
Hashtables\iHashtableResizeScale2 (default: 4)
If bAllowDynamicResizing is 1 then iHashtableResizeScale1 will determine the minimum level of occupancy at which a hashtable will be resized, and iHashtableResizeScale2 will determine how much larger its new size will be. Both numbers are actually exponents applied to 2, so a setting of 3 means a factor of 8, and a setting of 5 means a factor of 32. In theory reducing iHashtableResizeScale1 down to 1 might improve performance more, because it would increase the size of more hashtables. iHashtableResizeScale2 should probably be set to 1 or 2 more than iHashtableResizeScale1.

Hashtables\iHashtableResizeDelay (default: 20)
This is a number of milliseconds that OSR will stall for when resizing a hashtable. The idea is that while I can't prevent another thread from accessing the hashtable while I'm busy with it, I can, hopefully, prevent them from *starting* to access the hashtable. So I delay long enough that maybe, possibly, anyone who was already accessing the hashtable will finish up, then I do my stuff. That doesn't work on OBSE unfortunately because OBSE doesn't do the same things as Oblivion does, plus even when it does it doesn't use the vtables to do them. But atm I'm thinking that OBSE may only access them from the main thread, so if my resizer runs in the main thread then it doesn't have to worry about OBSE. Maybe.

Section: Overrides{}
This section contains information telling OSR how to find specific instances various types of objects that OSR knows about, and ways to treat those specific instances differently than the default settings for that type of object. Currently only things that actually get listed here are a few specific critical sections with different behaviors than most.


====================================
6. Version History:
====================================

version 1:
This was known as FPS Capper. All it did was FPS management.

version 2:
This was known as FPS Capper. All it did was FPS management.

version 3 beta 1:
The first version to be named Oblivion Stutter Remover. Sometimes freezes for several minutes at the main menu. NPC voice and face movements can screw up in dialogue.
version 3 beta 2: NPC voice and face movements can screw up in dialogue.

version 3 beta 3: NPC face movements can screw up in dialogue, but not nearly as bad as in beta 2.

version 3 beta 4:
Don't use this version! In some cases nearby NPCs would randomly die whenever you did a cell transition.
version 3 beta 5:
Reports of very rare drastic FPS drops, fixable by restarting Oblivion.

version 3 beta 6:
There was a long delay between beta 5 and beta 6, filled by many alpha releases. This was the first version of OSR to really do a decent job of actually reducing stutter for the average user. This is because of new features: critical section fairness tweaks, critical section suppression, and heap replacement. Unfortunately, heap replacement still has major problems for many users. bFix64Hertz was set to 0 by default in the ini, it should be 1 instead.

note: there was never a version 3 final. If there's enough demand I could make one up based off of version 3 beta 6 source code with a few fixes.

Version 4.1.0:
Major Changes:
Fallout 3 support: Doesn't provide as much benefit on Fallout 3, but it does help. See Fallout Stutter Remover.
.ini file: Completely different ini file format
Hashtable resizing: New feature for improving performance
Critical Sections: Generalized many special cases for critical sections, now much more adjustable from the ini file.
Heap Replacement: Fixed a few bugs, but I think it still has problems.
Version naming: Versions released to tesnexus are now called release versions instead of beta versions. Versions released to my ftp server are now called beta versions instead of alpha versions. The first digit of the version number ("4" in this case) is incremented only when major changes are made to configuration or distribution format. The 2nd digit of the version number ("1" in this case) is incremented each release version. The 3rd digit of the version number is incremented once for each beta version. Whenever a digit is incremented, all digits further to the right are reset to 0.

====================================
7. How This Works:
====================================

This is an OBSE plugin dll. It basically hacks Oblivion.

7.1: FPS Management:
The FPS management code monitors framerates and adjusts the flow of gametime. It mitigates stuttering by making Oblivion game logic not skip ahead when it does stutter. Effectively, frames that take a long time end up being in slow motion. This is done by making Oblivion act as if iFPSClamp were set to MinimumFPS, but only for frames that are slower than MinimumFPS. This may also improve stability. It can also impose a maximum framerate - some people perceive Oblivion as smoother when its framerate is prevented from exceeding half the refresh rate, plus this helps free up resources for Oblivions secondary threads.

The FPS management code can also puts the main thread of Oblivion to sleep for brief periods of time, which has been oberved to improve stutter for some people (though that functionality may have been made redundant by other things this plugin does).

7.2: Critical Sections:
Critical sections are microsoft-provided thread synchronization primitives that Oblivion uses internally to make sure that threads don't accidentally corrupt each other. OSR by default makes most critical sections attempt to play fair even at the cost of throughput, making sure that no thread hogs a resource that other threads need. However, one specific critical section is overriden to use a slightly less fair method, and another specific critical section is suppressed so that it has no effect at all. And that's all very configurable from the ini file. Also the spincounts get overriden.

7.3: Heap Replacement:
Oblivion uses a custom heap (aka memory manager aka malloc/free) implementation that appears to have been written by Bethesda specifically for Oblivion. Their implementation is flawed. Specifically, it performs really badly on multithreaded workloads, which Oblivion often is. This plugin now has the ability to replace the Oblivion heap manager with a variety of alternatives, most of which are MUCH faster on multithreaded workloads. Unfortunately, changing the heap implementation seems to cause Oblivion to become unstable for some users. I'm not certain if this is due to a flaw in my method of replacing the heap, or if this is due to bugs in Oblivion that happen to not crash with Oblivions vanilla heap.

The performance improvement offered by this is large (reduces stutter, reduces load times, makes certain menus faster, may improve FPS slightly) for many people, though some peoples installs of Oblivion seem to not multithread as much. Unfortunately, because it has a tendency to produce instability I have set this feature to default to disabled for the time being. However, given the large performance boost that many people see with this, I would suggest that users try turning this on, only turning it back off if they experience stability issues that seem to be related.

7.4: Hashtables:
Oblivion includes a bunch of hashtables for looking up all sorts of things. They use a poor hashtable implementation, but the real problem is they never resize their hashtables and the default sizes they use are targetted at an unmodded game and often rather small even for that. When a hashtable gets overful, performance drops. If a hashtable is underful then a tiny bit of memory may be wasted. Unfortunately, much of the hashtable code is inlined all over the place, and OBSE makes various assumptions about the hashtables as well, and its not at all clear to me what the relevant threading model is supposed to be, so changing them safely is quite difficult.

Still, I have some hashtable hooks, and they're gradually getting better. OSR can increase the size of hashtables once they get overful. The act of resizing them is fraught with problems however - it can cause crashes or glitches, and the methods I use to prevent it from doing so can cause small performance stutters or other crashes or glitches. Still, at this point I think it might be working kinda decently. In the future I may replace this or suplement this with overriding the initial sizes of certain hashtables.


====================================
8. Credits:
====================================

This plugin was made by me (Christopher Doty-Humphrey).

It would not have been possible without the enormous efforts made by the OBSE team. In addition, Ian Patterson (an OBSE team guy) has helped me through a lot of spots where I had trouble.

The original thread that prompted me to start this plugin was started by DeviusCreed.

Numerous testers have supplied useful feedback. In particular mashani's information about which settings produced which results for him helped me understand why early versions of this were producing unexpected benefits, and led to a number of the features and settings in later versions.

I would also like to thank badhair for pointing me at overfull hashtables as a cause of performance problems.

The following tools were used in the production of this plugin:
Oblivion, by Bethesda
OBSE and the OBSE source code
Microsoft Visual C++ 2008 Express Edition
IDA Free (Interactive Debugger, free version, version 4.9)
Cheat Engine (version 5.4)
Plus the obvious stuff like Windows XP, Notepad, and Firefox.

With the exception of Oblivion and Windows XP, all of those are available free of charge.

I've also had Hex Workshop and ollydbg recommended to me but haven't gotten around to trying them yet.

User avatar
lauren cleaves
 
Posts: 3307
Joined: Tue Aug 15, 2006 8:35 am

Post » Thu May 12, 2011 7:06 pm

The current stuff ongoing:

Critical Sections:
current stuff works pretty well for most people
however, some installs of Oblivion or Fallout have anomalous behavior that it doesn't work well on
possibly I should consider adding another mode to try to work well for all cases

Heap replacement:
needs more work on Fallout
still has trouble for some people on Oblivion, but this is believed to be impractical to fix

Hashtable resizing:
current approach for dynamic resizing appears to be working; may get enabled by default in 4.2
would like to also add some static resizing sometime

LCS full hooks:
Fallout-only, needs more work (buggy)
considering modifying CS stuff to split off LCS-like handling on Oblivion where possible if the full hooks look good enough on Fallout

Performance monitoring:
with a bit more work this might be possible to make in to a useful tool for diagnosing performance problems on Oblivion / Fallout

multithreaded culling / rendering:
At this point I know enough about what's going on I could probably move clipping plane checks into another thread; unfortunately, they account for only 1% of CPU usage. The stuff that accounts for the majority of CPU usage is not understood yet, and I'm not feeling very optimistic about splitting it across multiple threads atm.
User avatar
Alexxxxxx
 
Posts: 3417
Joined: Mon Jul 31, 2006 10:55 am

Post » Thu May 12, 2011 12:23 pm

I've had a remarkable experience: As you may remember I have recently enabled hashtable resizing, and it works very, very, VERY stable for me. I have a question: What is to expected to improve exactly having it enabled (if one can say something about that at all) ?

See, because I have posted a few days ago, I had this fight in a dungeon where me and my 2 campanions were fighting 5 Marauders (that was the quest for that Rockshatter club down in Anvil) and the fight became unplayable with FPS in the single digits. So that was with OSR 4.1 and HeapAlgo = 1 and NO hashtable resizing. Fine.

NOW with the addition of hashtable resizing, I had numerous fights in Silver Tooth Cave yesterday (which in OOO is a Goblin lair), where large numbers of Goblins swarmed my party of three (like with the Marauders) and the game continued to run way, WAAAYY better than before. The FPS were were very playable, can't remember exactly cuz fighting was hard. But totally playable, with just about no noticeable lag! If I try to remember precisely, the boss fight included 1 Goblin Warlord, 2 Shamans that were throwing spells, 2 Berserkers and at least 1 (but probably 2) Skrimisher plus 1 or 2 simple Goblins. I could go back and body-count, but definitely minimum of 7 enemies. My party fighting with enchanted weapons created additional animations... So HUGE fight with lots and lots of stuff going on!!

I don't know whether the Marauder scripts are more CPU-heavy than a bunch of Goblin fighting scripts. But if they were similar, the stress of the Goblin fight was definitely significantly higher than the Marauder fight. Yet the game ran much better! And did not crash ever in those fights. The boss fight alone I did at least three times cuz we got killed. Well I don't know if this can all be atrributed to hashtables, but that's the only thing I've changed between those 2 fights. So I'm more in love with OSR than ever, really! :hugs:
User avatar
Alex [AK]
 
Posts: 3436
Joined: Fri Jun 15, 2007 10:01 pm

Post » Thu May 12, 2011 4:04 pm

-snip-


Very interesting!
I'll put mine on straight away, see what it does.:)
User avatar
Love iz not
 
Posts: 3377
Joined: Sat Aug 25, 2007 8:55 pm

Post » Thu May 12, 2011 11:32 pm

Hashtables are a datastructure used to make searching for things fast. You want to be able to take a name or a formID or whatever and be able look up a pointer at a... somethingorother, without having to search all possible somethingorothers for ones matching that name or formID or whatever. A hashtable is typically the fastest way of going about it, provided that you don't have any problems with poor hashing or overfull tables. Oblivion uses lots of them, but has lots of problems with overfull tables. There are also a few problems with poor hashing in Oblivion, but those seem to be less significant.

When dynamic hashtable resizing is enabled, OSR will monitor all hashtables looking for overfull ones. When it finds an overfull hashtable, it will resize it to make it not overfull anymore. Doing that without crashing any other threads that may be examining the same hashtable simultaneously is problematic, but the current method seems to be working. The current method creates slowdowns every time a hashtable is resized, and since sometimes many hashtables get resized in rapid succession, it can occasionally create performance problems.

What it speeds up is any attempt to look anything up in a hashtable that would otherwise have been overfull. What code does that? I have no clue. Probably lots of code, but I don't know what it would be a limiting factor for. My expectation is that hashtable resizing would make a lot of things a little bit faster, with the speedup being bigger the more heavily modded the Oblivion install is. Well, more accurately, the slowdown that gets prevented being bigger the more heavily modded the Oblivion install is. One user described it as a 5 FPS improvement. I have never tried to measure a performance of it myself, asside from the details about how overfull hashtables get in the absense of it.

This is the first I've heard about it effecting specifically AI or combat performance.
User avatar
kitten maciver
 
Posts: 3472
Joined: Fri Jun 30, 2006 2:36 pm

Post » Thu May 12, 2011 12:18 pm

Well, I just installed the new version and enabled hashtable resizing and heap option 1. Min fps 15, max 45.

Initial brief testing looked like about a 5 fps gain running around outside. Haven't played with battles or extensively yet. I'll post back with some more tested results after a few days.

gothemasticator
User avatar
Rachel Cafferty
 
Posts: 3442
Joined: Thu Jun 22, 2006 1:48 am

Post » Thu May 12, 2011 11:58 am

Bought a new cpu yesterday, gone to a Q9550 from an E5200. No improvement in Oblivion. :(

Goes to show, there really is a hardware cap for this game. I can run the game at a solid 60 fps and no stutter on max settings wandering around, but put npcs into the picture and it all takes a nosedive.

If you'd like to take a look at logs of this, just tell me what to do.
User avatar
Richard Dixon
 
Posts: 3461
Joined: Thu Jun 07, 2007 1:29 pm

Post » Thu May 12, 2011 1:36 pm

Bought a new cpu yesterday, gone to a Q9550 from an E5200. No improvement in Oblivion. :(

Goes to show, there really is a hardware cap for this game. I can run the game at a solid 60 fps and no stutter on max settings wandering around, but put npcs into the picture and it all takes a nosedive.

If you'd like to take a look at logs of this, just tell me what to do.


Oh yah man, to bad you didn't post here before buying a quad core CPU. It is widely known that Oblivion lacks in multicore support. The nice thing though is you'll gain in everything else related to building your mods, cleaning mods, PyFFing meshes or using any other tools that would usually drain a single or dual core CPU. You might have a bit more head room in your new CPU that could possibly unlock some frames. I gained 17 FPS after OCing my dual core.
User avatar
Catherine N
 
Posts: 3407
Joined: Sat Jan 27, 2007 9:58 pm

Post » Thu May 12, 2011 9:42 am

thank you for this!

i have a HUGE performance gain compared to the beta 6...

:)
User avatar
Benjamin Holz
 
Posts: 3408
Joined: Fri Oct 19, 2007 9:34 pm

Post » Thu May 12, 2011 12:45 pm

I've had a remarkable experience: As you may remember I have recently enabled hashtable resizing, and it works very, very, VERY stable for me. I have a question: What is to expected to improve exactly having it enabled (if one can say something about that at all) ?


I think I know what I will be testing for my day off tomorrow :thumbsup: Now that I finally have my current mod list stable from CTDs
and my OC clocks stable. I can finally get some serious testing done with OSR. I reverted back to 3.6 beta during my CTD tests
just to be sure OSR wasn't a culprit. Now that I'm convinced it's not, it should be a fun go with the new hashtable resizing!
User avatar
Haley Merkley
 
Posts: 3356
Joined: Sat Jan 13, 2007 12:53 pm

Post » Thu May 12, 2011 8:46 am

@Nessh
The Q9550 is 300MHz faster than the E5200 so there should be a small improvement in performance. What graphics card do you have? Also, do you have vSync turned on? Performance and graphic mods?

As Far327 mentioned, overclocking might be able to get you some extra FPS during fights if you are adventurous and willing to taks a risk. Do be careful though and make sure the overclock is perfectly stable before you commit to it though (eg run http://downloads.guru3d.com/OCCT-%28OverClock-Checking-Tool%29-3.0.0-download-1880.html).
User avatar
Natasha Callaghan
 
Posts: 3523
Joined: Sat Dec 09, 2006 7:44 pm

Post » Thu May 12, 2011 10:20 am

I think I know what I will be testing for my day off tomorrow

far, you may have stated it before, but i'm too lazy to go back: what CPU do you have, what's the stock speed and what's your OC speed, if you don't mind?

I would be surprised if you were not positively surprised by the new OSR 4.1! Have fun! (I hope) :)
User avatar
Jordyn Youngman
 
Posts: 3396
Joined: Thu Mar 01, 2007 7:54 am

Post » Thu May 12, 2011 3:13 pm

Oh yah man, to bad you didn't post here before buying a quad core CPU. It is widely known that Oblivion lacks in multicore support.


Heh, I knew that already. I was just hoping the slightly better clock speed and vastly better L2 cache would help out. I didn't just buy it for Oblivion! ;)

@Nessh
The Q9550 is 300MHz faster than the E5200 so there should be a small improvement in performance. What graphics card do you have? [/url]).


A GTS 250. It's not a super card, but it's more than capable at handling vanilla graphics. I don't run any graphics mods any more even though the ding to my fps was slight. Throwing polygons and shader effects around isn't the problem though. It's npcs and combat that ruin things.
User avatar
Code Affinity
 
Posts: 3325
Joined: Wed Jun 13, 2007 11:11 am

Post » Thu May 12, 2011 6:54 pm

@Nessh
Agreed. I have a Geforce 7950 and it can run with most/all settings at best quality. I think that the problem is indeed the CPU. I hear that the Core i7 is more efficient than any of the Core 2 CPUs so that might be able to run Oblivion better. Otherwise, a stable overclock to the CPU might be the only other way of solving the low combat FPS problem.

Have you got any mods which optimise the meshes in the game (such as PyFFI)? These can also reduce CPU load. You could also try OSR's graphics culling setting. From what I can gather, it removes objects and pieces of the landscape from any frame that takes too long to process. This could be a good fix. I mean in combat, you probably won't notice that trees and rocks in the background are disappearing while fighting a group of enemies. Then they will all reappear when the fighting stops.

Otherwise, you will have to hope that Sky Ranger finds some ways of adding more multi-threading support to Oblivion.
User avatar
Matt Fletcher
 
Posts: 3355
Joined: Mon Sep 24, 2007 3:48 am

Post » Thu May 12, 2011 8:00 pm

I use oblivion stutter remover and streamline also. From what Im; read in different thread i might want to turn offf streamline and just use obilvion stutter remover instead for better performance. Please correct me if I'm wrong .
User avatar
Amber Ably
 
Posts: 3372
Joined: Wed Aug 29, 2007 4:39 pm

Post » Thu May 12, 2011 5:10 pm

far, you may have stated it before, but i'm too lazy to go back: what CPU do you have, what's the stock speed and what's your OC speed, if you don't mind?

I would be surprised if you were not positively surprised by the new OSR 4.1! Have fun! (I hope) :)


Intel E8600 Core2Duo.

Stock - 3.33Ghz
Overclock - 4.44Ghz

Looking forward to trying it out! I know everyone stands to gain from it.
User avatar
Baylea Isaacs
 
Posts: 3436
Joined: Mon Dec 25, 2006 11:58 am

Post » Thu May 12, 2011 7:50 pm

@Nessh
I think that the problem is indeed the CPU. I hear that the Core i7 is more efficient than any of the Core 2 CPUs so that might be able to run Oblivion better.


This is a true statement. i7 is certainly going to offer the best performance. I will definitely be getting a Westmere chip when they hit the market!
I did once buy a i7 920 chip and X58 board just to test them. (Took them back a couple days later) Anyways, I saw 15-20 FPS gain after compared
to my current rig. This was after OCing the chip to 4ghz. So yes, there is much to gain from a highend CPU.
User avatar
Ilona Neumann
 
Posts: 3308
Joined: Sat Aug 19, 2006 3:30 am

Post » Thu May 12, 2011 8:54 pm

Intel E8600 Core2Duo.

Hmm... not so different from mine which is E8400 but running only at stock 3 GHz... :embarrass:
4.44 GHz... that's :ooo: ... like 50% more than mine... Do you achieve that with conventional air cooling or water cooling? Nitrogen cooling? Liquid oxigen cooling?? :lol: Do you have to increase voltage for that? Be brief, do not elaborate. Sorry I'm so curious. SkyRanger-1, I promise these were my last OT questions. :)
User avatar
Sherry Speakman
 
Posts: 3487
Joined: Fri Oct 20, 2006 1:00 pm

Post » Thu May 12, 2011 9:16 pm

Hmm... not so different from mine which is E8400 but running only at stock 3 GHz... :embarrass:
4.44 GHz... that's :ooo: ... like 50% more than mine... Do you achieve that with conventional air cooling or water cooling? Nitrogen cooling? Liquid oxigen cooling?? :lol: Do you have to increase voltage for that? Be brief, do not elaborate. Sorry I'm so curious. SkyRanger-1, I promise these were my last OT questions. :)


LOL! :biglaugh: @ Liquid oxigen cooling!

It's air cooled with very good case airflow and a killer heatsink fan. I have my voltage cranked as high as Intel suggests is stable for my model chip which is 3.625v. The biggest reason the CPU OCs so well is because A. It's 45nm and B. It's an E stepping of the 45nm chip. I think my mobo got some great OCing stability results as well. EVGA 790i FTW. There are other voltages I adjusted as well, but I won't elaborate here on it.
User avatar
lolly13
 
Posts: 3349
Joined: Tue Jul 25, 2006 11:36 am

Post » Thu May 12, 2011 8:13 pm

@Far327
Maybe you could switch to water cooling for your components. It might then mean less stress and micro-management of your air flow, especially on a hot day.

As for the Core i7, a 4GHz i7 runs better than a 4.4GHz Core 2 Duo? I suppose I can't be surprised. A magazine I read once estimated that you need to overclock a Core 2 Quad by 500MHz to get the same improvement to performance as you would get by overclocking a Core i7 by 200MHz.
User avatar
JUan Martinez
 
Posts: 3552
Joined: Tue Oct 16, 2007 7:12 am

Post » Thu May 12, 2011 11:38 am

What happened to bExtraProfiling? :)
User avatar
James Smart
 
Posts: 3362
Joined: Sun Nov 04, 2007 7:49 pm

Post » Thu May 12, 2011 5:16 pm

What happened to bExtraProfiling? :)
???
The code for it was first enabled in 4.1.1. It was also present in 4.1.2. There has been no further beta releases since 4.1.2. Why would you think that something happened to it?
User avatar
Schel[Anne]FTL
 
Posts: 3384
Joined: Thu Nov 16, 2006 6:53 pm

Post » Thu May 12, 2011 1:01 pm

???
The code for it was first enabled in 4.1.1. It was also present in 4.1.2. There has been no further beta releases since 4.1.2. Why would you think that something happened to it?


Wasn't it present in 3.x? Must be my imagination, anyway I must have v4.1.0 from tesnexus(recently did a clean installation), my bad :).
User avatar
Heather Kush
 
Posts: 3456
Joined: Tue Jun 05, 2007 10:05 pm

Post » Thu May 12, 2011 1:26 pm

I do not recall an option by that name in 3.x, though I could have forgotten something. The option currently going by that name is new, written around the time of 4.0.7 and first enabled in a release in 4.1.1. It measures the time spent in various bits of Oblivion code, mostly (but not entirely) things that happen about once per frame.
User avatar
Queen of Spades
 
Posts: 3383
Joined: Fri Dec 08, 2006 12:06 pm

Post » Thu May 12, 2011 8:01 pm

I ran it and found nothing interesting(I could paste it here but basically it's just graphic1, graphic2 and culling that take all the time).
I wanted to test because I found out changing resolution or shadows had no impact at all on fps(not even a little!). Apparently the slow down is mainly caused by lighting(I was testing in Vilverin with real lights + Dungeon actors have torches), which is handled in the culling section I guess(total newb on 3d but I guess it calculates which object each light affect and it's limited not by the graphic card but by Oblivion's code, which is apparently terrible at this :P).
Anyway very interesting profiling option you added.

Oh and I assumed it was there before because I saw a post in a previous thread with the CallPerf thing, looked in the source on how to enable it and saw the option was commented out so I assumed it was implemented and then deactivated for some reason(source code on TES). Entirely my fault :).
User avatar
Dezzeh
 
Posts: 3414
Joined: Sat Jun 16, 2007 2:49 am

Next

Return to IV - Oblivion