"Congress is so strange. A man gets up to speak and says nothing. Nobody listens - and then everybody disagrees."
- Boris Marshalov
More pages: 1 ... 11 ... 21 ... 31 ... 41 ... 51 ... 61 ... 71 ... 81 ... 91 ... 101 ... 111 ... 121 ... 125 126 127 128 129 130 131 132 133 134 135 ... 141 ... 151 ... 161 ... 171 ... 181 ... 191 ... 201 ... 211 ... 221 ... 231 ... 241 ... 251 ... 261 ... 271 ... 281 ... 291 ... 301 ... 311 ... 321 ... 331 ... 341 ... 351 ... 361 ... 371 ... 381 ... 391 ... 401 ... 411 ... 421 ... 431 ... 438
Query FailedAxel
Friday, August 6, 2010

I think this is just a huge waste of time.

Even if there would be a difference on a modern superscalar out of order CPU (which I doubt), the time spent in the DirectX runtime is so large that the time saving will not be measurable.

And if you are calling DirectX functions in such a frequency that it does you are fucked anyway.

reavenk
Thursday, August 5, 2010

I'm guilty of skimming the top and only reading the bottom, so I assumed ASM was being used. And I jumped the gun and completely forgot about requesting the DirectX object. So I've come back to apologize twice.

Sean Barrett
Thursday, August 5, 2010

Last time I checked, Direct3D API objects were COM objects, not C++ objects. They have a well-defined systematic way of being accessed from C which must be consistent and forever obeyed. This happens to be exactly the C++ vtable layout, of course, but there's no sense in which this is cheating or delving into proprietary aspects; if somebody decided to change how the C++ compiler laid things out, they would stop being C++ objects but would remain COM objects, I think. (Of course everything would break in practice, but at a minimum you've got binary compatibility guaranteeed on the old versions.)

I didn't know that the GL went through a jump table as Barbie suggests. I always assumed the ICD model had the vendors supplying their own opengl32.dll to avoid this, but perhaps not.

Also, the OpenGL functions appear to lack a 'this' pointer, but they implicitly have one--each thread has a render context, so instead of explicitly being passed 'this' they have the implicit 'rc' that they have to get from thread-local storage. I seem to recall hearing that the OpenGL Windows devs cajoled the appropriate OS folk into giving them a hardcoded tls slot directly off of FS so they can get to it in one instruction.

Humus
Thursday, August 5, 2010

Barbie, the v-table is located in read-only memory, in the code segment I think. It never changes at runtime. In fact, if you attempt to alter it, the code will crash. Of course, the D3D runtime could of course avoid using any form of standard C++ calls to create the object and simply create it as a struct and create a v-table dynamically and fill in whatever pointers it wants and send that back to you. In that case you shouldn't crash when attempting to write it though, unless they explicitely tagged the memory page as read-only after filling it in.

Reavenk, that's a nice trick for when you want a specific implementation, but it relies on the function pointer being resolvable at compile-time. That's impossible for D3D. If you attempt this on a device pointer you'll get a link error. That's because ID3D11DeviceContext is an abstract interface. It only has pure virtual functions. It should also be noted that if D3D really provided a base implementation in the ID3D11DeviceContext class and only overrided specific functions in deriving classes, using your trick would make it call the wrong function. The actual target function you need cannot be resolved at compile-time if the class type is variable, so a function pointer that you fill in at runtime is most certainly needed.
As for ASM, I don't know quite what you mean. I didn't write any assembly code for this, it's all plain C++. I used the disassembly view though for verifying that I'm getting the results I'm expecting. Even if you live in the C++ world you have to peek into the machine code once in a while to get an understanding of what the generated code looks like.

Reavenk
Thursday, August 5, 2010

You don't have to save the function pointer, there's syntax for getting access to it when calling it, which is done at compile time. Which might also save you a little more by using a constant function pointer value instead of reading it from a variable.

It also prevents you from going into ASM and the flaws on ASM (non-portability and readability), and works with the compiler instead of subverting it.

pointer->Class::FnCall(); //See link below
http://pastebin.com/59XHskjP

Barbie
Thursday, August 5, 2010

Beware though, this is obviously not language-compliant (you're looking under the hood). And I can also imagine that the indirection that the vtable provides could be hijacked by the runtime (think modifying the vtable at runtime ). Even if it's not now, it might happen in the future. (Unlikely, but still).

Oh, and BTW, the GL may be C static functions, the first thing it does on windows is calling into an indirection table that's part of the ICD model (for the windows-exposed GL functions at least. Things are different for extensions methods).
All in all, I would not recommend the method!

Cyril Crassin
Thursday, August 5, 2010

I love this kind if hack :-D
Thanks for the trick Humus ! That can also be applied in many other API relying on virtual calls.

Marek Olsak
Thursday, August 5, 2010

The following article explains how to turn most virtual function calls into inline ones and still have the same level of abstration. It's an example that virtual functions may have nearly no impact on performance when used wisely.

See here:
http://www.gamedev.net/reference/articles/article2763.asp

More pages: 1 ... 11 ... 21 ... 31 ... 41 ... 51 ... 61 ... 71 ... 81 ... 91 ... 101 ... 111 ... 121 ... 125 126 127 128 129 130 131 132 133 134 135 ... 141 ... 151 ... 161 ... 171 ... 181 ... 191 ... 201 ... 211 ... 221 ... 231 ... 241 ... 251 ... 261 ... 271 ... 281 ... 291 ... 301 ... 311 ... 321 ... 331 ... 341 ... 351 ... 361 ... 371 ... 381 ... 391 ... 401 ... 411 ... 421 ... 431 ... 438