I have a real-time application that streams one (1) or two (2) 1920x1080x60 video frames to three screens.
99% of the time the system runs just fine. Every so often, the call to glXMakeCurrent will take an extremely long time to return. On the order of ~20ms.
I am using the most current nvidia driver, 352.55, on a RedHat Enterprise Workstation 6.7 system with 6 real/12 hyper-threaded cores.
I have even set the affinity of the two threads, Capture and Render, into different processor ranges. Capture runs in processors 8 thru 11, while Render runs in processors 4 thru 7.
Under normal conditions, the whole frame will run in ~6-7ms. It is just the errant frame that is causing me heartache.
When I am tracking an object in the visual scene, losing frames causes my control loop problems.
Switching the bound context on a thread can be very expensive. You should consider a model where you have a context per thread, which should avoid the need to rebind the context (i.e. do a glXMakeCurrent) after startup. You say you have processors 8-11 devoted to rendering, but it’s not clear whether you have one thread per context/screen.
I don’t have a solution for you but possibly an idea to explore. One of the things MakeCurrent does is flush the commands on the currently-bound context (and possibly waiting for queued commands to complete) before it binds the new context. It’s possible that some/most of the cost is actually in performing this flush or finish operation rather than changing the bound context. You can try putting a glFinish right before your glXMakeCurrent, executed only when a previous context was bound successfully. Then see how your time is distributed.
Also, a question: Are you doing anything to prevent the GPU from “reading ahead” into future frames? This might result in spurious extra “flush” time being consumed. Try adding a glFinish right after your SwapBuffers call, to force your draw thread to synchronize with the scan-out of video frame. This should prevent your draw thread from queuing up multiple frames and accumulating a big backlog of work.