Search code examples
c#multithreadingsharpdx

Improving threading CPU usage in C#


I am using SharpDX to make a GUI interface and associated code to allow control of the mouse cursor/emulate key presses but even at idle my app uses 15%+ cpu to the point where it increases my CPU temp +10C while my app is running, here is controller update loop running in its own thread:

private void CallToChildThread()
{
    Program.stateOld = controller.GetState();
    while (controller.IsConnected)
    {
        Program.stateNew = controller.GetState();
        CheckButtons();
        Point cursor;
        GetCursorPos(out cursor);

        short tx;
        short ty;
        tx = Program.stateNew.Gamepad.LeftThumbX;
        ty = Program.stateNew.Gamepad.LeftThumbY;

        float x = cursor.X + _xRest;
        float y = cursor.Y + _yRest;

        float dx = 0;
        float dy = 0;

        // Handle dead zone
        float lengthsq = tx * tx + ty * ty;
        if (lengthsq > DEAD_ZONE * DEAD_ZONE)
        {
            float mult = speed * getMult(lengthsq, DEAD_ZONE, acceleration_factor);

            dx = getDelta(tx) * mult;
            dy = getDelta(ty) * mult;
        }

        x += dx;
        _xRest = x - (int)x;

        y -= dy;
        _yRest = y - (int)y;
        SetCursorPos((int)x, (int)y);
        Program.stateOld = Program.stateNew;
    }
}

CheckButtons is just a function i use to check which buttons have been pressed, I've tried running this inside the controller update thread but I cannot get the buttons to perform as expected.

the while() and GetCursorPos contribute the most towards the total cpu usage. I've tried to compare packet numbers so my app is idle when the controller isn't being used but that causes major issues with handling cursor position(it's very slow and intermittent)

Edit: I've set the thread to background and its priority to BelowNormal but that didn't improve CPU usage very much


Solution

  • This is a tight loop, so it's going to fully use a CPU core. Just add a Thread.Sleep(10) at the end of each iteration. Adjust the delay if it's not responsive enough, but with 10 ms it'll be polling the controller state 100 times per second, which is already a lot.

    private void CallToChildThread()
    {
        Program.stateOld = controller.GetState();
        while (controller.IsConnected)
        {
            // Your update logic
            Thread.Sleep(10); // Adjust the delay as needed
        }
    }
    

    Also, note that lowering the thread priority is not going to decrease CPU usage. It just tells your thread to yield to another if there's not enough CPU available for everybody, which obviously isn't the case.