C++ multi-thread bound CPU

Windows multithreading

windows.hA multi-thread solution is provided in , and the function to create a multi-thread is

//返回值:一个HANDLE类型的值,表示线程的句柄,可用于等待线程等函数
HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES   lpThreadAttributes, // 不用管,一般为NULL
  SIZE_T                  dwStackSize,        // 堆栈大小,一般为0,表示默认值
  LPTHREAD_START_ROUTINE  lpStartAddress,     // 函数指针
  __drv_aliasesMem LPVOID lpParameter,        // 参数指针
  DWORD                   dwCreationFlags,    // 不用管,一般为0
  LPDWORD                 lpThreadId          // 线程id,一般设为NULL
);

In order to understand this function, the following is the simplest example

#include<iostream>
#include<windows.h>

// 编写了一个我的线程函数
DWORD WINAPI MyThread(LPVOID ps)
{
    
    
	int *n = (int *)ps;
	for (int i = 0; i < 3; ++i)
		printf("执行线程%d, i=%d\n", n[0], i);
	return 0L;
}

int main()
{
    
    
	// 创造线程
	int id1 = 1, id2=2;
	CreateThread(NULL, 0, MyThread, &id1, 0, NULL);
	CreateThread(NULL, 0, MyThread, &id2, 0, NULL);
	system("PAUSE");
	return 0;
}

Among them, MyThreadis a function used to create a new thread, and its input parameter psis a LPVOIDpointer of a type. After the parameter is passed in, this pointer is converted into an integer pointer (int *), and then assigned to another integer pointer n, and then forreferenced in the loop This integer pointer.

In mainthe function, CreateThreada thread is created and executed through the function, where the function to be executed is MyThreadand the parameter passed in is id1, id2the address of . The result after execution is

执行线程2, i=0
执行线程1, i=0
执行线程1, i=1
执行线程1, i=2
执行线程2, i=1
执行线程2, i=2
请按任意键继续. . .

Windows scheduling and binding CPU

As a mature operating system, in order to make full use of the CPU, Windows will dynamically allocate CPU resources occupied by threads to ensure that each CPU core is not tired; on the other hand, as a mature CPU, Intel, in order to fully consider the relationship between performance and energy consumption Balanced, when the CPU is not running at full load, it will automatically reduce the frequency.

The combination of these two is that Windows dynamically allocates CPU cores so that each CPU is not overloaded; then Intel dynamically plans energy consumption to reduce the frequency of each core. As a result, the frequency of the CPU is getting lower and lower, and the resources occupied by Windows are getting less and less, so the performance is getting worse and worse.

The above description is of course slightly exaggerated, but the truth is that, in order to verify this, the above MyThreadfunction can be slightly changed,

DWORD WINAPI MyThread(LPVOID ps)
{
    
    
    int* n = (int*)ps;
    int cpu = GetCurrentProcessorNumber();
    for (int i = 0; i < 5; ++i) {
    
    
        printf("在CPU%d上执行线程%d, i=%d\n", cpu, n[0], i);
        Sleep(100);
    }
    return 0L;
}

In this way, you can view the CPU used each time the thread is executed, and find that the CPU used for each run is random.

Manually allocate CPU through windows.hin , the method of use is very simpleSetThreadAffinityMask

int main()
{
    
    
	// 创造线程
	int id1 = 1, id2=2;
	auto th1 = CreateThread(NULL, 0, MyThread, &id1, 0, NULL);
	SetThreadAffinityMask(th1, 0x01);
	auto th2 = CreateThread(NULL, 0, MyThread, &id2, 0, NULL);
	SetThreadAffinityMask(th2, 0x02);
	// 记得等待线程结束
	system("PAUSE");
	return 0;
}

The effect is as follows

在CPU0上执行线程1, i=0
在CPU1上执行线程2, i=0
请按任意键继续. . . 在CPU1上执行线程2, i=1
在CPU0上执行线程1, i=1
在CPU0上执行线程1, i=2
在CPU1上执行线程2, i=2
在CPU1上执行线程2, i=3
在CPU0上执行线程1, i=3
在CPU1上执行线程2, i=4
在CPU0上执行线程1, i=4

Guess you like

Origin blog.csdn.net/m0_37816922/article/details/130288853