cpp multi thread sync via std::atomic<bool;

Posted Fred1987

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cpp multi thread sync via std::atomic<bool;相关的知识,希望对你有一定的参考价值。

#include <atomic>
#include <chrono>
#include <cmath>
#include <condition_variable>
#include <ctime>
#include <fstream>
#include <functional>
#include <future>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <mutex>
#include <queue>
#include <random>
#include <sstream>
#include <thread>
#include <uuid/uuid.h>
#include <vector>

std::string get_time_now()

    std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
    time_t raw_time = std::chrono::high_resolution_clock::to_time_t(now);
    struct tm tm_info = *localtime(&raw_time);
    std::stringstream ss;
    std::chrono::seconds seconds = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
    std::chrono::milliseconds mills = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
    std::chrono::microseconds micros = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch());
    std::chrono::nanoseconds nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch());
    ss << std::put_time(&tm_info, "%Y%m%d%H%M%S")
       << std::setw(3) << std::setfill(\'0\') << std::to_string(mills.count() - seconds.count() * 1000) << ","
       << std::setw(3) << std::setfill(\'0\') << std::to_string(micros.count() - mills.count() * 1000)
       << std::setw(3) << std::setfill(\'0\') << std::to_string(nanos.count() - micros.count() * 1000);
    return ss.str();


char *uuid_value = (char *)malloc(40);
char *get_uuid()

    uuid_t new_uuid;
    uuid_generate(new_uuid);
    uuid_unparse(new_uuid, uuid_value);
    return uuid_value;


std::atomic<bool> _is_write_finish(false);

void write_into_file(const std::string &file_name, const int &len)

    std::fstream w_file(file_name, std::ios::app);
    if (!w_file.is_open())
    
        std::cout << "Create or open " << file_name << " failed" << std::endl;
        return;
    

    std::stringstream ss;
    int loops = len / 1000000;
    int remainder = len % 1000000;
    static int num = 0;
    if (loops > 0)
    
        for (int i = 0; i < loops; i++)
        
            for (int j = 0; j < 1000000; j++)
            
                ss << ++num << "," << get_uuid() << std::endl;
            
            w_file << ss.str();
            std::cout<<num<<std::endl;
            ss=std::stringstream();
        
    

    if(remainder>0)
    
        for(int i=0;i<remainder;i++)
        
            ss<<++num<<","<<get_uuid()<<std::endl;
        
        w_file<<ss.str();
        ss=std::stringstream();
    

    w_file.close();
    _is_write_finish=true;


void print_file(const std::string&file_name)

    while(!_is_write_finish.load())
            
    
    std::fstream read_file(file_name,std::ios::in);
    if(!read_file.is_open())
    
        std::cout<<"Open "<<file_name<<" failed!"<<std::endl;
        return;
    

    std::string line;
    while(getline(read_file,line))
    
        std::cout<<line<<std::endl;
    
    read_file.close();
    std::cout<<get_time_now()<<",finishi in "<<__FUNCTION__<<std::endl;


void atomic_write_read_sync(const std::string &file_name, const int &len)

    std::thread t1(write_into_file,std::cref(file_name), std::cref(len));
    std::thread t2(print_file,std::cref(file_name));
    t1.join();
    t2.join();
    std::cout<<get_time_now()<<",finish in "<<__FUNCTION__<<std::endl;


int main(int args, char **argv)

    atomic_write_read_sync(argv[1],atoi(argv[2]));

 

Compile

g++ -std=c++2a -I. *.cpp -o h1 -luuid -lpthread

 

Run

./h1 log.txt 11111111

 

 

 

 

The key to synchronize multiple threads in before-and-write relationships located at std::atomic<bool> the third variable,with false default value,when before thread finished set the atomic variable to true

While in the after thread,in while loop it run nothing because the load() is false,until the atomic variable is true,it run the following code sequentially.

TiG-BEV:Multi-view BEV 3D Object Detection via Target Inner-Geometry Learning——论文笔记

参考代码:TiG-BEV

1. 概述

介绍:由于相机的BEV感知算法缺少或较难预测准确深度信息,导致下游任务性能掉点。对此,文章提出了一种基于目标内在几何信息(TIG:Target Inner-Geometry)的知识蒸馏信息约束载体,其可以有效将Lidar准确的3D感知信息迁移给图像,进而实现camera下性能提升。文章使用的是基于LSS的方法,其知识迁移的主要是在BEV特征图上完成的,也就是提出了一种基于object(检测目标)inter-keypoints和inter-channel的知识迁移。除此之外,还对LSS中深度估计部分做了优化,增加了object中相对深度约束。

对于给camera提供深度感知能力,可以将现有不同的方法划分为如下几种类型:

  • 1)深度监督:类似于LSS中添加深度预测分支,直接通过网络有监督或是无监督形式得到深度表达。
  • 2)BEV特征图知识迁移:使用Lidar数据去获取BEV特征,之后将其于camera获得的BEV特征进行逐点近似。这样的方法缺点也很明显,引入太多噪声,没有对其中的目标着力关注。
  • 3)文章的TIG方法:在深度估计部分出了LSS自带的深度监督约束,还增加object内部相对深度约束。在BEV特征蒸馏部分,在object内部采用inter-keypoint和inter-channel近似的方式实现知识蒸馏。

2. 方法设计

2.1 网络pipeline

文章的方法流程图见下图所示:

其主要优化便是对深度估计部分和BEV特征蒸馏部分做了优化。

2.2 深度估计分支添加相对约束

深度估计除了LSS中采用深度bins预测损失之外,还考虑目标本身内在的相对深度信息。如下图展示了object目标中不同部分深度是不一样的:

对此,对于需要检测的目标设置了目标内部相对深度约束,其实这点类似于深度估计方法中structrual-loss。对于相对深度的参考点文章是通过预测过程中选择于GT深度差异最小的点( j j j代表object的索引):
( x r , y r ) = arg min ⁡ ( x , y ) ∈ S ^ j ( S j g t ( x , y ) − S ^ j ( x , y ) ) (x_r,y_r)=\\argmin_(x,y)\\in\\hatS_j(S_j^gt(x,y)-\\hatS_j(x,y)) (xr,yr)=(x,y)S^jargmin(Sjgt(x,y)S^j(x,y))
之后便是目标中所有的像素计算与参考点的深度差异(预测结果和GT中分别进行):
r d j ( x , y ) = d j ( x , y ) − d j ( x r , y r ) rd_j(x,y)=d_j(x,y)-d_j(x_r,y_r) rdj(x,y)=dj(x,y)dj(xr,yr)
r d j g t ( x , y ) = d j g t ( x , y ) − d j g t ( x r , y r ) rd_j^gt(x,y)=d_j^gt(x,y)-d_j^gt(x_r,y_r) rdjgt(x,y)=djgt(x,y)djgt(xr,yr)
之后便是对上述深度相对差异进行约束:
L d e p t h R = ∑ j = 1 M ∣ ∣ R ^ j − R j g t ∣ ∣ 2 L_depth^R=\\sum_j=1^M||\\hatR_j-R_j^gt||_2 LdepthR=j=1M∣∣R^jRjgt2
这里也可采用ranking-loss替代,效果应该会更好。

不同的相对深度约束方式对性能带来的影响:

2.3 BEV特征图上的蒸馏

同样这里采用了object上实现特征图对齐,不过对齐的方式采用了inter-keypoints和inter-channel的形式,其实也就是特征图在不同空间下的表达。这里对于首先对于BEV上object对应的区域采用均匀采样 N N N个点,并通过双线性插值得到camera和Lidar对应的特征表达: f j 2 d , f j 3 d ∈ R N ∗ C f_j^2d,f_j^3d\\in R^N*C fj2d,fj3dRNC。那么接下来便是去最小化它们的特征表达,也就是在下图所示的空间上实现:

inter-channel上:
定义camera和Lidar特征表达:
A j 2 d = f j 2 d f j 2 d T ,   A j 3 d = f j 3 d f j 3 d T A_j^2d=f_j^2df_j^2d^T,\\ A_j^3d=f_j^3df_j^3d^T Aj2d=fj2dfj2dT, Aj3d=fj3dfj3dT
通过L2范数约束:
L b e v I C = ∑ j = 1 M ∣ ∣ A j 2 d − A j 3 d ∣ ∣ 2 L_bev^IC=\\sum_j=1^M||A_j^2d-A_j^3d||_2 LbevIC=j=1M∣∣Aj2dAj3d2

inter-keypoints上:
定义camera和Lidar特征表达:
B j 2 d = f j 2 d T f j 2 d ,   B j 3 d = f j 3 d T f j 3 d B_j^2d=f_j^2d^Tf_j^2d,\\ B_j^3d=f_j^3d^Tf_j^3d Bj2d=fj2dTfj2d, Bj3d=fj3dTfj3d
通过L2范数约束:
L b e v I K = ∑ j = 1 M ∣ ∣ B j 2 d − B j 3 d ∣ ∣ 2 L_bev^IK=\\sum_j=1^M||B_j^2d-B_j^3d||_2 LbevIK=j=1M∣∣Bj2d论文阅读MEAL: Multi-Model Ensemble via Adversarial Learning

论文笔记之:Heterogeneous Image Features Integration via Multi-Modal Semi-Supervised Learning Model

论文笔记:Missing Value Imputation for Multi-view UrbanStatistical Data via Spatial Correlation Learning

TiG-BEV:Multi-view BEV 3D Object Detection via Target Inner-Geometry Learning——论文笔记

multi-CPU, multi-core and hyper-thread--转

Multi-threaded Map Reduce in Rust