我可以理解如何编写一个使用多个进程或线程的程序:fork()一个新进程并使用IPC,或创建多个线程并使用这些通信机制.
我也理解上下文切换.也就是说,只有一次CPU,操作系统为每个进程安排时间(并且有大量的调度算法),从而我们实现了同时运行多个进程.
现在我们拥有多核处理器(或多处理器计算机),我们可以在两个独立的核心上同时运行两个进程.
我的问题是关于最后一个场景:内核如何控制进程运行的核心?哪些系统调用(在Linux,甚至是Windows中)在特定核心上安排进程?
我问的原因是:我正在为学校开展一个项目,我们将在那里探索最近的计算主题 - 我选择了多核架构.关于如何在这种环境中编程(如何监视死锁或竞争条件)似乎有很多材料,但在控制各个核心本身方面却没有太多.我希望能够编写一些演示程序并提供一些汇编指令或C代码,以实现"看,我在第二个内核上运行无限循环,查看该特定内核的 CPU利用率峰值" .
任何代码示例?还是教程?
编辑:为了澄清 - 很多人都说这是操作系统的目的,应该让操作系统处理这个问题.我完全同意!但那时我所要求的(或试图感受到)是操作系统实际上做的事情.不是调度算法,而是"一旦选择了核心,必须执行哪些指令才能让核心开始获取指令?"
是否有一种编程方法可以为Linux操作系统在c/c ++中为进程设置CPU亲和性.
据推测,有一个库或简单的asm blob可以获取我正在执行的当前CPU的编号.
我在尝试着:
使用处理器固定同时运行16个副本(每个核心2个副本)
在处理器固定(每个核心2个副本)的同时运行8个副本,并在某个功能说功能1完成后将处理器核心翻转到最远的核心.
我面临的问题是如何选择最远的处理器.
有些朋友建议使用sched_getaffinity和sched_setaffinity,但我认为没有找到任何好的例子.
我目前正在使用openmp在4核phenom2上并行化程序.但是我注意到我的并行化对性能没有任何作用.当然我以为我错过了一些东西(falsesharing,通过锁定序列化......),但是我无法找到类似的东西.此外,从CPU利用率来看,程序似乎只在一个核心上执行.从我发现的sched_getcpu()应该给我核心的Id,执行调用的线程当前安排在.所以我写了以下测试程序:
#include <iostream>
#include <sstream>
#include <omp.h>
#include <utmpx.h>
#include <random>
int main(){
#pragma omp parallel
{
std::default_random_engine rand;
int num = 0;
#pragma omp for
for(size_t i = 0; i < 1000000000; ++i) num += rand();
auto cpu = sched_getcpu();
std::ostringstream os;
os<<"\nThread "<<omp_get_thread_num()<<" on cpu "<<sched_getcpu()<<std::endl;
std::cout<<os.str()<<std::flush;
std::cout<<num;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的机器上,这给出了以下输出(随机数当然会有所不同):
Thread 2 on cpu 0 num 127392776
Thread 0 on cpu 0 num 1980891664
Thread 3 on cpu 0 num 431821313
Thread 1 on cpu …Run Code Online (Sandbox Code Playgroud)