Heim  >  Artikel  >  System-Tutorial  >  Der Dual-Core-CPU-Killer lässt Ihren Linux-Prozess schneller laufen!

Der Dual-Core-CPU-Killer lässt Ihren Linux-Prozess schneller laufen!

WBOY
WBOYnach vorne
2024-02-14 11:50:131083Durchsuche

Bei der Verwendung von Linux-Systemen stoßen wir häufig auf CPU-intensive Aufgaben wie Datenverarbeitung, Programmkompilierung usw., deren Ausführung eine große Menge an Rechenressourcen erfordert. Wenn die Hardwarekonfiguration unseres Systems jedoch niedrig ist, führt dies zu einer langsamen Aufgabenausführung und beeinträchtigt unsere Arbeitseffizienz erheblich. Um dieses Problem anzugehen, wird in diesem Artikel eine Technologie namens „CPU-Bindung“ vorgestellt, mit der ein Prozess an einen bestimmten CPU-Kern gebunden werden kann, wodurch die Ausführungseffizienz des Prozesses verbessert wird.

Der Dual-Core-CPU-Killer lässt Ihren Linux-Prozess schneller laufen!

Für normale Anwendungen ist der Standardplanungsmechanismus des Betriebssystems kein Problem. Wenn ein Prozess jedoch eine höhere Betriebseffizienz erfordert, muss darüber nachgedacht werden, ihn an einen separaten Kern zu binden, um den durch die Planung auf verschiedenen Kernen verursachten Overhead zu reduzieren.

Nachdem ein Prozess/Thread an einen bestimmten CPU-Kern gebunden wurde, wird der Prozess immer auf diesem Kern ausgeführt und vom Betriebssystem nicht für andere Kerne geplant. Der gebundene Kern kann jedoch weiterhin für die Ausführung anderer Anwendungen eingeplant sein.

Planung von Multi-Core-CPUs durch das Betriebssystem

Derzeit unterstützen sowohl Windows als auch Linux die Planung und Verwaltung von Multi-Core-CPUs.

Der Kern der Softwareentwicklung in einer Multicore-Umgebung ist die Multithread-Entwicklung. Dieses Multithreading stellt nicht nur Multithreading in der Softwareimplementierung dar, sondern erfordert auch den Einsatz von Multithreading-Technologie in der Hardware.

Der Fokus von Multicore-Betriebssystemen liegt auf der Prozesszuordnung und -planung. Bei der Prozesszuweisung werden Prozesse angemessenen physischen Kernen zugewiesen, da verschiedene Kerne unterschiedliche gemeinsame Nutzung und historische Betriebsbedingungen haben. Einige physische Kerne können den Second-Level-Cache gemeinsam nutzen, während andere unabhängig sind. Wenn ein Prozess mit Datenfreigabe einem Kern mit einem gemeinsam genutzten sekundären Cache zugewiesen wird, wird die Leistung erheblich verbessert, andernfalls kann die Leistung beeinträchtigt werden.

Die Prozessplanung umfasst Themen wie Echtzeitleistung und Lastausgleich. Aktuelle Forschungsthemen konzentrieren sich hauptsächlich auf die folgenden Aspekte:

  1. Parallele Entwicklung und Gestaltung von Programmen
  2. Zeitabhängigkeit mehrerer Prozesse
  3. Aufgabenzuweisung und -planung
  4. Zwischengespeicherte Fehlerfreigabe
  5. Ständiges Zugriffsproblem
  6. Kommunikation zwischen Prozessen
  7. Konkurrenz um Ressourcen innerhalb von Multiprozessorkernen

Die Situation, wenn Multiprozess und Multithread auf dem CPU-Kern ausgeführt werden, ist wie folgt:
Wenn jeder CPU-Kern einen Prozess ausführt, besteht keine Notwendigkeit, den Kontext beim Wechseln zwischen CPU-Kernen zu berücksichtigen, da die Ressourcen jedes Prozesses unabhängig sind Wenn jeder CPU-Kern einen Thread ausführt, müssen die Threads manchmal Ressourcen gemeinsam nutzen, sodass diese Ressourcen von einem Kern der CPU auf einen anderen kopiert werden müssen, was zusätzlichen Overhead verursacht

Binden Sie den Prozess so, dass er auf dem CPU-Kern ausgeführt wird

Überprüfen Sie, wie viele Kerne die CPU hat

Verwenden Sie cat /proc/cpuinfo, um CPU-Informationen anzuzeigen, die folgenden zwei Informationen:

Prozessor, geben Sie an, welcher CPU-Prozessor

ist CPU-Kerne, geben Sie die Anzahl der Kerne jedes Prozessors an
Sie können auch den Systemaufruf sysconf verwenden, um die Anzahl der CPU-Kerne zu ermitteln:

#include 

int sysconf(_SC_NPROCESSORS_CONF);/* 返回系统可以使用的核数,但是其值会包括系统中禁用的核的数目,因 此该值并不代表当前系统中可用的核数 */
int sysconf(_SC_NPROCESSORS_ONLN);/* 返回值真正的代表了系统当前可用的核数 */

/* 以下两个函数与上述类似 */
#include 

int get_nprocs_conf (void);/* 可用核数 */
int get_nprocs (void);/* 真正的反映了当前可用核数 */

Ich verwende eine virtuelle Maschine mit 2 Prozessoren. Jeder Prozessor hat nur einen Kern, was zwei Kernen auf einem Prozessor entspricht.

Verwenden Sie den Taskset-Befehl

Prozess-PID abrufen

-> % ps
PID TTY TIME CMD
2683 pts/1 00:00:00 zsh
2726 pts/1 00:00:00 dgram_servr
2930 pts/1 00:00:00 ps

Überprüfen Sie, auf welcher CPU der Prozess gerade ausgeführt wird

-> % taskset -p 2726
pid 2726's current affinity mask: 3

Die angezeigte Dezimalzahl 3 wird in Binärzahl umgewandelt und die niedrigsten beiden sind 1. Jede 1 entspricht einer CPU, sodass der Prozess auf 2 CPUs läuft.

Der angegebene Prozess wird auf CPU1 ausgeführt

-> % taskset -pc 1 2726
pid 2726's current affinity list: 0,1
pid 2726's new affinity list: 1

Beachten Sie, dass die CPU-Beschriftung bei 0 beginnt, sodass cpu1 die zweite CPU darstellt (die erste CPU-Beschriftung ist 0).

Zu diesem Zeitpunkt ist die Anwendung zur Ausführung an cpu1 gebunden, wie unten gezeigt:

-> % taskset -p 2726
pid 2726's current affinity mask: 2

Binden Sie die CPU beim Starten des Programms

#启动时绑定到第二个cpu
-> % taskset -c 1 ./dgram_servr&
[1] 3011

#查看确认绑定情况
-> % taskset -p 3011
pid 3011's current affinity mask: 2

Verwenden Sie den Systemaufruf sched_setaffinity

sched_setaffinity kann einen Prozess an eine bestimmte CPU binden.

#define _GNU_SOURCE /* See feature_test_macros(7) */
#include 

/* 设置进程号为pid的进程运行在mask所设定的CPU上
* 第二个参数cpusetsize是mask所指定的数的长度
* 通常设定为sizeof(cpu_set_t)

* 如果pid的值为0,则表示指定的是当前进程
*/
int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);

int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);/* 获得pid所指示的进程的CPU位掩码,并将该掩码返回到mask所指向的结构中 */

Beispiele

#include
#include
#include
#include
#include

#define __USE_GNU
#include
#include
#include
#include
#define THREAD_MAX_NUM 200 //1个CPU内的最多进程数

int num=0; //cpu中核数
void* threadFun(void* arg) //arg 传递线程标号(自己定义)
{
cpu_set_t mask; //CPU核的集合
cpu_set_t get; //获取在集合中的CPU
int *a = (int *)arg;
int i;

printf("the thread is:%d\n",*a); //显示是第几个线程
CPU_ZERO(&mask); //置空
CPU_SET(*a,&mask); //设置亲和力值
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//设置线程CPU亲和力
{
printf("warning: could not set CPU affinity, continuing...\n");
}

CPU_ZERO(&get);
if (sched_getaffinity(0, sizeof(get), &get) == -1)//获取线程CPU亲和力
{
printf("warning: cound not get thread affinity, continuing...\n");
}
for (i = 0; i if (CPU_ISSET(i, &get))//判断线程与哪个CPU有亲和力
{
printf("this thread %d is running processor : %d\n", i,i);
}
}

return NULL;
}

int main(int argc, char* argv[])
{
int tid[THREAD_MAX_NUM];
int i;
pthread_t thread[THREAD_MAX_NUM];

num = sysconf(_SC_NPROCESSORS_CONF); //获取核数
if (num > THREAD_MAX_NUM) {
printf("num of cores[%d] is bigger than THREAD_MAX_NUM[%d]!\n", num, THREAD_MAX_NUM);
return -1;
}
printf("system has %i processor(s). \n", num);

for(i=0;ifor(i=0; ireturn 0;
}

Laufergebnisse

-> % ./a.out
system has 2 processor(s).
the thread is:0
the thread is:1
this thread 0 is running processor : 0
this thread 1 is running processor : 1

Binden Sie Threads zur Ausführung auf dem CPU-Kern

Binden Sie Threads mit der Funktion pthread_setaffinity_np an den CPU-Kern. Ihr Prototyp ist wie folgt definiert:

#define _GNU_SOURCE /* See feature_test_macros(7) */
#include 

int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);

Compile and link with -pthread.

Die Bedeutung jedes Parameters ähnelt sched_setaffinity.

Beispiele

#define _GNU_SOURCE
#include 
#include 
#include 
#include
 

#define handle_error_en(en, msg) \
do { errno = en; perror(msg);
 exit(EXIT_FAILURE); } while (0)

int
main(int argc, char *argv[])
{
int s, j;
cpu_set_t cpuset;
pthread_t thread;

thread = pthread_self();

/* Set affinity mask to include CPUs 0 to 7 */

CPU_ZERO(&cpuset);
for (j = 0; j if (s != 0)
handle_error_en(s, "pthread_setaffinity_np");

/* Check the actual affinity mask assigned to the thread */

s = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
if (s != 0)
handle_error_en(s, "pthread_getaffinity_np");

printf("Set returned by pthread_getaffinity_np() contained:\n");
for (j = 0; j if (CPU_ISSET(j, &cpuset))
printf(" CPU %d\n", j);

exit(EXIT_SUCCESS);
}

Laufergebnisse

-> % ./a.out
Set returned by pthread_getaffinity_np() contained:
CPU 0
CPU 1

Durch die Einleitung dieses Artikels haben wir gelernt, wie man mithilfe der CPU-Bindungstechnologie einen Prozess an einen bestimmten CPU-Kern bindet und dadurch die Ausführungseffizienz des Prozesses erheblich verbessert. In tatsächlichen Anwendungen können wir je nach Szenario und Bedarf geeignete CPU-Bindungslösungen auswählen, um den besten Leistungsverbesserungseffekt zu erzielen. Ich hoffe, dass dieser Artikel den Lesern helfen kann, die CPU-Bindungstechnologie besser zu verstehen und anzuwenden und eine höhere Arbeitseffizienz bei der Verwendung von Linux-Systemen zu erzielen.

Das obige ist der detaillierte Inhalt vonDer Dual-Core-CPU-Killer lässt Ihren Linux-Prozess schneller laufen!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:lxlinux.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen