Yeah, I'm curious. How high is the call overhead to a C dll function? Would it be viable to make hundreds of calls per second? And how many simple calculations could DM do in the time it calls a function?
I may yet do benchmarks myself, but I thought I should first ask here, since someone else may know.
ID:132235
Oct 14 2011, 8:43 am
|
|
Oct 14 2011, 8:55 am
|
|
As far as I heard the call is very slow as it has to convert data into char* type.
|
In response to Zaoshi
|
|
It's actually quite quick. In my tests for simple things like string manipulation it has been about 4 to 5 times faster over heavy usage than the most efficient methods possible in DM.
|
Pretty slick, from what I've seen. It really depends what you intend to do with it though, if you feel the call overhead (and not the call itself?) is going to be a problem.
You can't for example expect to offload a lot of math calculation to a DLL for performance improvements (complex matrix manipulation aside), just because you'll spend too long constructing a string on your end and de-constructing the returned string (in DM) for simple math offloads to C to be worth while. Once in the C code of course, you're flying away. Perhaps you can go into more detail on what you intend to do? |
In response to Stephen001
|
|
I'm considering offloading some of the atmosphere calculations in SS13 to C. Basically, I'd have a separate process running with its own memory(since I think dll's can't store information between calls), then have a DLL that communicates with that process via some fast method.
Feedback to BYOND would happen through two methods. One would be direct getter/setter calls from BYOND. The other one would be "events" that the separate process stores in a list, and BYOND can poll. Now I'm simply asking myself if it'd be more efficient to transmit data in small chunks through many function calls, or in large chunks through few function calls, the latter requiring a lot more parsing. |
In response to CIB
|
|
CIB wrote:
Now I'm simply asking myself if it'd be more efficient to transmit data in small chunks through many function calls, or in large chunks through few function calls, the latter requiring a lot more parsing. You could do a combination - have your C library store its results on the heap or in static memory, and then request the results, so your DM code would look something like this: proc/some_very_complex_calculation() The 'context' variable becomes a pointer (I did some terrain generation stuff which treated it as an actual pointer, i.e. context would be the integer or hex representation of a pointer) which points to some heap-allocated structure. Then, you can query that structure for your results. This way you can do your complex calculation efficiently, you don't have to parse out multiple results using string parsing (other than the text2nums you'll probably need) and you only have to ask for the results you need. |
Okay, I made some benchmarks to see what's going on. I'm using an empty function in a C dll that returns immediately.
Benchmarked Code Time in ns The last benchmark is the problem. The combination of num2text and call() shouldn't take 24000ns, and indeed it only happens on the first time I run the benchmark. If I run the benchmark twice in a row, the second one will only take 6000ns, which is slightly more acceptable. The DM code for the last benchmark is as follows: mob/verb/test() And the C function: <code> extern "C" __declspec(dllexport) const char* test(int argc, char* args[]) { return 0; } </code> So, what's going on here? Why does the combination of num2text and call() cost so much more than the individual actions? Any way a BYOND dev could look into this and possibly fix it? |
In response to Nadrew
|
|
Well it depends I guess.
However to make heavy usage of single .dll call it'll need a lot of information. Converting numbers to list, then list into string will take time on both ends. I think it would be nice if we could use .dll similar to C/C++ style; without converting everything to string, but pass floats and char* as they are in DM. |
In response to Zaoshi
|
|
As pointed out by the benchmarks, that'd lead to around a 8x speedup, so I agree. I'm considering making a ticket for this, though it's unlikely it'll be done.
|
In response to CIB
|
|
I haven't worked much with DLL files, but right now I can't quite imagine how it can be accomplished =/
|
In response to CIB
|
|
CIB wrote:
I'm considering offloading some of the atmosphere calculations in SS13 to C. Basically, I'd have a separate process running with its own memory(since I think dll's can't store information between calls), then have a DLL that communicates with that process via some fast method. Just coincidentally, I was thinking of doing something like that a while ago. I ended up spreading the calculations over multiple ticks in DM instead, which is far easier than translating everything to C++. It might be worth it to offload either all of the calculation or none. Offloading part of it would mean you spent too much time running num2text and text2num. Also, a DLL can store as much information as you want, and start new threads, etc... Basically, anything that can be done by an EXE can also be done by a DLL loaded into it. Another random idea: If you know how CheatEngine works, that could theoretically be replicated in a BYOND DLL and you'd be able to instantly communicate between C and DM (have the C code scan for a DM variable and update it). But that seems very hacky and unreliable. |