View previous topic :: View next topic |
Author |
Message |
chris421
Joined: 07 Apr 2005 Posts: 53
|
Posted: Sun Dec 31, 2006 20:20 Post subject: 2DA to MySQL migration |
|
|
Uploaded my ERF, my performance results, and my sql script for migrating NWN2's 2DA files to MySQL here.
My initial comments about achieving a 10-12 fold improvement over the standard "Get2DAString" didn't factor the overhead I incurred while spamming SpeakStrings to verify the resulting data. Removing the SpeakStrings showed the true throughput appears between 150-160 microseconds per look-up. This is in comparison to Get2DAString's throughput of 23-76 milliseconds.
UPDATE: Performed some additional file IO profiling (via Filemon) of NWNX4+NWN2 Server. Even with my modified global scripts the server still hits some of those zip files (under .\data) pretty damn often (1000s of times at startup). "Get2DAString" is one of those embedded, immutable engine functions that can't be overridden. So as much as I'd like my function to divert all 2DA look-ups, I don't see that happening. Also remember changes made to MySQL tables don't automatically modify the source 2DAs. You'll have to export your MySQL changes and put them into your server's .\override folder to catch those embedded calls. Probably would require a NWN2 Server restart as well.
So my function is great for homebrewed scripts that require speedy access to a lot of data. But if you're looking to just speed up native NWN2 Server functions you may be better off setting up a small RAMDisk and divert your .\override folder to it. Prior to starting your NWN2 Server I would copy the smaller of the .\data zips into it (ideally extracted).
Don't ask me why NWN2 Server hits files like Sounds.zip, Music.zip, NWN2_Materials.zip, VO.zip, etc., even after I've intentionally disabled sound in the server's INI. There appear to be 100s of MB of client-specific files, wholly unnecessary for server operation, being read in at server startup. Definitely do not copy those to RAMDisk. On my server I'm experimenting with the zips I can safely remove altogether to decrease file IO and footprint. |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Sun Dec 31, 2006 22:42 Post subject: |
|
|
Nice idea ! If someone with a little debugging knowledge would hook Get2DAString, you could get rid of the calls at startup as well. _________________ Papillon |
|
Back to top |
|
|
chris421
Joined: 07 Apr 2005 Posts: 53
|
Posted: Sun Dec 31, 2006 23:34 Post subject: |
|
|
Wow, hadn't even considered a plug-in option for hooking Get2DAString.
You think it's possible?
I'm no developer. Wouldn't even know where to begin unfortunately. But I gather the premise would be to monitor the server process; await, intercept, and modify the request, returning the new result via some module stored string--to the original requesting script???
I guess that's what you guys do here. Cool. |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Mon Jan 01, 2007 15:43 Post subject: |
|
|
Yes, you would hook the function and then intercept all calls to it, or maybe even let the original function run if no row was found in the database. Usually, doing this takes between 2 and 4 days, so while it's not too hard to do, it's quite some work . _________________ Papillon |
|
Back to top |
|
|
chris421
Joined: 07 Apr 2005 Posts: 53
|
Posted: Mon Jan 01, 2007 23:07 Post subject: |
|
|
There seem to be as many opinions as people regarding the "when", "how often" and "to what limits" 2DAs are cached at server startup (and afterward, per request). See Bioware thread here.
Assuming Bioware/Obsidian are currently employing some 2DA caching logic, if someone tackled this plug-in, hooking Get2DAString would also have the added benefit of reducing fragmented server process memory.
The 2DAs would already be in memory on the MySQL side. Allowing the additional NWN2 server-side caching would only defeat the purpose of having dynamically updateable tables.
Really wish I could contribute to this more. |
|
Back to top |
|
|
Gryphyn
Joined: 20 Jan 2005 Posts: 431
|
Posted: Tue Jan 02, 2007 0:12 Post subject: |
|
|
chris421 wrote: | There seem to be as many opinions as people regarding the "when", "how often" and "to what limits" 2DAs are cached at server startup (and afterward, per request). See Bioware thread here.
Assuming Bioware/Obsidian are currently employing some 2DA caching logic, if someone tackled this plug-in, hooking Get2DAString would also have the added benefit of reducing fragmented server process memory.
The 2DAs would already be in memory on the MySQL side. Allowing the additional NWN2 server-side caching would only defeat the purpose of having dynamically updateable tables.
Really wish I could contribute to this more. |
Bio only cache two 2DA's, the two most recently used.
Hooking the Get2DAString() function would be a great step forward.
The major benefit would be that all of the most-hit 2DA's would be cached (by the database) and these 2DA's become dynamic.
If you're happy with read-only access to the data, loading them into "in-memory" tables is the same as caching them all.
But using a database (SQL) to lookup data using a row-column reference is not very efficient -- read the C# class code -- what Obi have done, is load each column into a list (array) and access the data via an index into this list. A database (SQL ) doesn't work this way... It'll still be quick, it will be the database caching aspect that provide the biggest gains.
Think outside the box a little and the database provides you with VIEWS. Create a few views that define the relationships between 2DA's and you're got some very powerful access to 2DA data. Access multiple 2DA's with one Get2DAString() call. (access the master-row, to get reference data.)
Cheers
Gryphyn |
|
Back to top |
|
|
Tenkawa
Joined: 25 Aug 2005 Posts: 15
|
Posted: Tue Jan 02, 2007 18:11 Post subject: |
|
|
Any interest in backporting this to NWNX2 if it works?
Tenkawa |
|
Back to top |
|
|
Grinning Fool
Joined: 12 Feb 2005 Posts: 264
|
Posted: Wed Jan 03, 2007 6:18 Post subject: |
|
|
Another alternative to consider -- a specific 2da processing plugin that handles it in the same fashion as the toolset: indexed arrays. Nearly all lookups are done by index (as opposed to value); this would mean even the largest files wou ld be readable faster than either a database, or native 2da can offer. _________________ Khalidine, a NWN2 persistent world
Looking for volunteers. |
|
Back to top |
|
|
|