Jump to content

  • Log In with Google      Sign In   
  • Create Account

Shannon Barber

Member Since 23 Jun 2000
Offline Last Active Today, 11:25 AM

#5303564 Multithreaded User Interface

Posted by on 01 August 2016 - 05:46 PM

You just have to render it to a separate plane and if you're not running that low-level then render-to-textures and implement your own double or triple buffering.  

It's worth looking for an extension to get a plane if you try it.



I'm not sure where the notion of fast-enough UI code is coming from - in my experience it's the slowest thing there is.

In cars we use separate threads for overlays because they are so slow and we have to meet performance targets for rendering gauges.

#5303224 Is This A 'thread Deadlock'?

Posted by on 30 July 2016 - 01:55 PM

That's a primitive (with a reader-writer) which means updating it is atomic which means it's not a locking problem.

He didn't use 'volatile' so the check got optimized out.
Adding locking will probably fix the issue but it's not guaranteed! and it's overkill for such a simple case.



volatile int g_done;

#5301027 Finding that balance between optimization and legibility.

Posted by on 16 July 2016 - 07:10 PM

There is no possible way that code speeds up the calculation of sin and cos values for vectors and it introduces problem with reentrancy (it's not thread safe).


When optimizing this sort of code there are three things you must do to achieve state-of-the-art performance.

1) Ensure you are using the greatest known mathematical reduction of the algorithm

2) Eliminate all branches (even if it means more calculations)

3) Use vectorizing operations, e.g. SIMD, NEON, AVX, et. al.  


Optimizing the code for vectoring operations can be very annoying.

Algorithms tend to favor separate arrays for each element/dimension as opposed to interleaved arrays which are more conveniently to deal with.
This cuts down on loading and packing time of the MD registers and that can be critical to utilizing all available computation units.


Doing the above and eliminating any IEEE-754 or C-standard overhead (e.g. if the rounding rules of the unit is different than the standards then it has to perform a conversion when storing) is how you make it fast.

The old fsincos instruction got it done in about 137 clock cycles; SSE2 and newer should have faster or more vectorized options.

If you can sacrifice accuracy then you can use an estimation of the sin and cos values and those algorithms are generally just multiplies and accumulates and you can get it done in a lot less than 100 clock cycles.

#5294857 responsiveness of main game loop designs

Posted by on 03 June 2016 - 02:53 PM

To do this optimally you need a buffer of input events with hardware time-stamps.

I was hoping that DirectInput would evolve towards that but it was abandoned and we're back to sucking messages from the pump.

That at least provides an ordered list of events but without the time-stamps you cannot even implement something as simple as pulling back the plunger for a pinball game accurately.

You get quantized to your polling rate and experience jitter corresponding to your input-stack and thread stability.


You could compensate for this by introducing the uncertainty of your input into your hit detection.

When you receive an event you know it happened between between 'just now' and one polling period ago which gives you a delta-time.


Humans do not act "at 5Hz".  

I can push a button for less than 10 ms and routinely demonstrate how HMI's cannot handle button presses that quick (and we show on an oscilloscope that the button was indeed pressed for 7~12 ms).


60 Hz vs. 120 Hz makes a notable difference for FPS games and it's probably due to the triple-buffering.

3 x 1/60 -> 50 ms. That's an eternity.

#5290999 Custom editor undo/redo system

Posted by on 10 May 2016 - 12:15 PM

The (de)serialization (second) approach can have a significant performance impact for moderate data-sets.

In a tool I wrote long ago we had to stop doing it that way and use the command pattern with undo/redo stacks (otherwise every time the end-user made a trivial modification there was a pause as the data was serialized.)

#5290183 Is it C# Territory?

Posted by on 04 May 2016 - 08:03 PM


Your good reason is "We have hundreds of thousands of man hours invested in our giant aging C++ code base, thus we'll be keeping that around. kthxbye."


Sunk cost fallacy...


A good reason would involve comparing the expected results of the new product against the quality of the existing product to see if the value of improvement exceeds the implementation cost and risks.



... and that cost would be hundreds of millions of dollars.

#5289321 Question about Open World Survival Game Engines

Posted by on 29 April 2016 - 02:50 PM

You're going about this completely backwards. Normally seeing you gather a team of engineers based on your pitch (and proper compensation of course), and you let them decide what technology to use for the project, since they'll be able to make a much more educated decision than you ever will.


I actually disagree. Just like running a guild, you have to pick the game and schedule first then recruit people that fit and want it.
If you just grab a bunch of people because they are good at X/Y/Z you will end up with a group of talented people that have no feasible way of working together.

#5289313 Question about Open World Survival Game Engines

Posted by on 29 April 2016 - 02:15 PM

For a professional project I would see if I could license Forgelight 2 (that's the SOE/Daybreak engine used in PS2 and H1Z1).

Next I would look at Unreal 4 and determine the work it would take to scale to large worlds - ARK is progressing albeit with some issues.

Practically speaking Unreal 4 is way easier to "get off the ground" with than wooing Daybreak to license FL2 to a vaporware team - especially when the plan is to create a competing project.


Programmers will be the least of your problems.

(There are a lot of programmers with boring day-jobs that will be willing to moonlight on an interesting project.)

The biggest problem is core business organization and project management.

There is no demonstrated way to complete such a project *on schedule* without an operating budget.

Mods, total-conversions, get made but they are generally not completed according to the original schedule.

The next major problem is the creation and integration of high-quality artwork and sound.


For structuring such a thing I would create a bitcoin-mining-like value generation and then assign it to the people working on it.

There's some software infrastructure to create for tracking (e.g. a tray-icon tool you click to clock-in/clock-out, detect away, detect screwing around on reddit, et. al.) and just that infrastructure could be its own company.

By bitcoin-mining-like I mean I would track the time people put in and have accomplishment of milestones unleash value that is then distributed among the people that contributed time to make it happen.

That amount becomes how much of the company they own (e.g. issue private stock).

#5289298 Returning by value is inevitable?

Posted by on 29 April 2016 - 01:34 PM

Anyone care to explain what is wrong with the static variable solution? I've used this for years and always thought it was a convenient and fast solution.


It's not technically different that returning the result in a global variable except it's even less obvious what it going on.

(Others have pointed out why this bad; breaking thread-safety and I presume also exception safety.)

Over the past 10 years or so all such code in the C standard library has been deprecated and replaced by better designed functions.


e.g. You suggested they do this:

float g_result;
void do_stuff(float a, float b)
   g_result = sqrtf(a*a + b*b);

#5289293 Data alignment on ARM processors

Posted by on 29 April 2016 - 01:16 PM

The best way to solve this problem really depends on the details.


Given what you have posted: since you have to perform big/little endian reordering anyway, you can get de-aliasing for free if you use a macro instead of a function as-long-as you write the macro to access the data byte-by-byte.


If the function adapts to the system/data then you need a corresponding no-swap macro that is hard-coded to move 4 bytes (that will be much faster than invoking memcpy for such a small amount of data).

#5289290 Should getters and setters be avoided?

Posted by on 29 April 2016 - 01:08 PM

Take the new C# compiler Roslyn. The old compiler was written in C++ while Roslyn is C# with everything immutable. Conventional thinking would be that C++ would be faster than a .NET language but even with the object churn the new compiler is far far faster.



The MSVC compilers are known for how slow they execute and compile code - they were about 10x slower than Borland's compilers and even gcc is faster today. I don't know why but they have "always" been that way so it's something in their legacy design that was not dumped until Roslyn.

Given C#'s bucketing memory allocation and garbage collection they probably just pool all memory used until compilation is complete then dump everything at shutdown and that is where I suspect most of the speed-up comes from so immutability has no impact on the compilation time.

#5285899 Input Polling - Low Latency API

Posted by on 08 April 2016 - 02:39 PM

The state of input is rather depressing.  

What we really want is an interrupt-driven system that feeds into a time-stamped queue for later processing.
Under-the-hood anything dealing with the keyboard must work close to this way and I assume the mouse and joystick as well  (movement or button press generates a USB packet?). They probably don't time-stamp the data though.
(The only thing I know of that does work this way is CAN devices.)


To do this today I believe you would have to write a driver that interacts with the other system drivers if-not replace them.



With keyboard and mouse though, perhaps I should implement a message pump and push states to an std::set. Then I could poll the set instead of the API. That could at the very least prevent stale states from being read.

That's essentially what GetKeyState does.

I think you still want to use GetAsyncKeyState.
It has a bit that indicates the key was pressed after that last call to GetAsyncKeyState and a bit to indicate the current state - I believe this is the closest you can get to the interrupt-driven state of the keyboard from user-land Windows (without writing your own driver).


I think Microsoft actually looked at improving this and that's when they said well ... just use the existing message-pump and key events.
There's no time-stamps but everything is in order and you shouldn't miss anything (unless Windows focus is messed up).

#5285891 Should getters and setters be avoided?

Posted by on 08 April 2016 - 02:00 PM

I abhor functions literally called 'getX' 'setX' but often people really mean properties when they say get/set and properties are quite useful with or without syntactic-sugar built into the language to explicitly support them.

The references article seems to be advocating for immutability which is ... an interesting concept out there but it doesn't really have a place with imperative languages.  
You'd be better suited to using LISP than C++ to explore immutable designs and there's probably something tailored for immutability out there by now - this idea is at least 20 years old and probably 40 or 50. (If your design is based on immutable objects it becomes possible to prove its correctness.)


Reading over the article I don't really see a strong argument - not stronger than the weak ones they list.
What is the real difference between setBall/getBall and GiveBall/TakeBall ?



We're not getting her name. We're asking her to tell us her name. See the difference?

Um ... nope. Get is a just a sloppy word that has a lot of definitions and in-context it means the same thing.



The distinction is that a property/accessors/get-set should not perform a lot of work and should not affect another object.  
They are free to do things to maintain the internal consistency of the object or do light work to get you the value you want.  

e.g. If I have a class that represents a measurement (a value and tolerance) I will probably store the value in SI units and have properties that return the values in other units.

#5285889 Why learn STL library

Posted by on 08 April 2016 - 01:52 PM

The STL was a ground-breaking design at the time of its release and understanding it will help you understand how to use data-structures more effectively to solve problems and help teach you how to do it in a way that is systematic and less prone to bugs.  


e.g. Iteration over containers is a key concept.  
Iterators enclosing the contents are always defined as [begin, end) (meaning what begin references is in the container but what end references is not in the container).  


I believe it was Alexander Stepanov (key designer for the STL) who said that the syntax of C++ templates was the worst thing he has ever had to code with but it was the only tool available that allowed him to codify his ideas into a usable implementation. 20+ years later and that hasn't really changed.  


In modern context "the STL" refers to the container templates (and supporting code) in the C++ standard library.

#5285534 Why is my struct destructor not called?

Posted by on 06 April 2016 - 10:00 PM

Why would it destroy the object twice?

You stomp over the '500' instance with the a = A(); call.


You are dabbling in an area that I think is unique to C++.

Other languages like Java, C#, et. al. don't (easily or at-all) allow you to construct an object on the stack.

C++ won't garbage collect either so if you did this with (heap) pointers you would leak  the '500' instance.


You could explicitly invoke the dtor before you invoke the ctor again.


a = A();