c++ - 为什么我的线程执行在 CPU 内核之间跳跃?

标签 c++ multithreading

我最近开始尝试使用 std::thread 并尝试运行一个小程序,在单独的线程中显示网络摄像头源,我正在使用 OpenCV。我这样做只是为了“教育”目的。我注意到线程似乎一直在内核之间跳跃,这让我觉得很奇怪,因为我认为从效率/性能的角度来看,这种更改的开销不值得。有人知道这种行为的根源/原因吗? 简短免责声明 --> 我是 StackOverflow 的新手,所以如果我遗漏了什么,请告诉我。

A snapshot of my system monitor - Ubuntu

#include <stdio.h>
#include <opencv2/opencv.hpp> //openCV functionality
#include <time.h> //timing functionality
#include <thread>



using namespace cv;

using namespace std;

void webcam_func(){
    Mat image;



namedWindow("Display window");

VideoCapture cap(0);

if (!cap.set(CAP_PROP_AUTO_EXPOSURE , 10)){
    std::cout <<"Exposure could not be set!" <<std::endl;
    //return -1 ;
}


if (!cap.isOpened()) {

cout << "cannot open camera";

    }
int i = 0;
while (i < 1000000) {

cap >> image;

Size s = image.size();
int rows = s.height;
int cols = s.width;

imshow("Display window", image);
double fps = cap.get(CAP_PROP_FPS);
//cout << "Frames per second using video.get(CAP_PROP_FPS) : " << fps << endl;

//cout <<"The height of the video is " <<rows <<endl;
//cout <<"The width of the video is " <<cols <<endl;
std::thread::id this_id = std::this_thread::get_id();   
std::cout << "thread id -->  " << this_id <<std::endl;
waitKey(25);

i++ ;
std::cout <<"Counter value " <<i <<std::endl; 

    }


}

int main() {

std::thread t1(webcam_func);    

while(true){

}


return 0;

}

最佳答案

默认的 Linux 调度程序在可用处理单元(例如内核或硬件线程)上为给定量程(时间片)安排任务(例如线程)。如果任务进入休眠模式等待某事(输入、锁定等),则可以中断此量程。 waitKey(25) 正是这样做的:它使您的线程等待一小段时间。线程执行被中断并完成了上下文切换。操作系统可以在这段时间内执行其他任务。当计算线程再次准备就绪时(因为已经超过 25 毫秒),调度程序可以再次调度它。它尝试在同一个处理单元上执行任务以减少开销(例如缓存未命中),但是当计算任务被调度回来时,先前的处理单元仍可以被另一个线程使用。当没有很多就绪任务或只是贪婪的任务时,这种情况不太可能发生。此外,一些处理器支持 SMT(又名超线程)。例如,许多 x86-64 Intel 处理器支持每个内核 2 个硬件线程共享相同的缓存。位于同一核心上的 2 个硬件线程之间的上下文切换要便宜得多(例如,缓存未命中率要低得多)。另请注意,Linux 调度程序并不像大多数其他调度程序那样完美。事实上,几年前它是伪造的,甚至无法在可能的情况下填充所有可用内核(参见:The Linux Scheduler: a Decade of Wasted Cores)。最后,请注意,在主流 Linux PC 上,上下文切换的(直接)开销不超过几十微秒,因此每隔几十毫秒进行一次就可以了(<1% 的开销)。

关于c++ - 为什么我的线程执行在 CPU 内核之间跳跃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72921127/

相关文章:

c++ - 如何在数组中存储地址 - C++?

multithreading - RuntimeError : main thread is not in main loop with Matplotlib and Flask

java - 如何在所有包含的线程完成之前阻止子例程结束?

c++ - 线程安全计数器c++11

c# - Monitor.Enter 可以抛出异常吗?

c++ - Qt 5.5 程序崩溃与 QStringListModel

android - 如何使用 android ndk 的原生相机库?

c++ - 初始化指针时写访问冲突

java - java中有没有更好的并行调用api的方法?

c++ - C2870 模糊符号错误