自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(100)
  • 收藏
  • 关注

原创 如何链接未被使用的符号

也就是说,在一个.o文件中,只要其中一个符号被链接进来,剩下的符号也会被链接进来(哪怕是没有被使用的)。这里面需要注意的–whole-archive后面是想要全量链接的库名,之后要使用–no-whole-archive避免后面的库也全量链接。还有一个问题,如果只想链接一个.o文件中被使用的符号,而把其它未被使用的符号删去,应该怎么做?什么也没有输出,Register没有被调用,说明Register符号并没有被链接进来。我们知道,在ld链接静态库过程中,通常只有被使用到的符号才回被链接进可执行文件中。

2023-10-22 18:06:03 234

原创 C语言关于&与&&运算符

需要具体分析funcA()和funcB()的返回值分布与复杂度,如果funcA()和funcB()复杂度很低,并且大部分情况下返回1,那么funcA() & funcB()的效率可能会高些;如果funcA()和funcB()复杂度较高,并且有可能返回0,那么funcA() && funcB()会高一些。上述代码中表达式funcA() & funcB() 与 funcA() && funcB() 哪一个效率更高?funcB() && funcA() 期望耗时为50。那么能否说明&的效率比&&要高呢?

2023-09-02 17:54:24 1633

原创 复制滞后问题

复制滞后问题主从复制要求所有写请求都经由主节点,而任何副本只能接受只读查询。对于读操作密集的负载,是一个不错的选择:创建多个从副本,将读请求分发给这些从副本,从而减轻主节点负载并允许读请求就近满足。在这种扩展体系下,只需要添加更多的从副本,就可以提高读请求的服务吞吐量。但是,这种方法实际上只能用于异步复制,如果试图同步复制所有的从副本,则单个节点故障或者网络中断将使整个系统无法写入。不幸的是,如果一个应用正好从一个异步的从节点读取数据,而该副本落后于主节点,则应用可能会得到过期的信息。这会导致数据库中

2022-03-02 21:07:45 545

原创 数据复制三种模式

数据复制为何需要数据复制使数据在地理位置上更接近用户,从而降低访问延迟。当部分组件出现故障,系统依然可以继续工作,从而提高可用性。扩展至多台机器以同时提供数据访问服务,从而提高读吞吐量。主从复制指定某一个副本为主节点。当客户写数据库时,必须将写请求发送给主节点,主节点首先将新数据写入本地存储。其他节点则全部称为从节点。主节点把新数据写入本地存储后,然后将数据更改作为复制的日志或更改流发送给所有的从节点。每个从节点获得更改日志或更改流之后将其应用到本地,且严格保持与主节点相同的写入顺序。

2022-03-02 20:52:55 1497

原创 C++STL中Allocator分析

C++STL中Allocator分析C++ SGI STL的allocator分为两级:第一级配置器:超过128bytes的内存分配通过第一级分配器进行分配。第二级配置器:不超过128bytes的内存分配通过第二级分配器进行分配。为了简单起见,文本在讨论的时候无考虑多线程的场景以及模板化。第一级配置器第一级配置器的实现比较简单,直接通过malloc请求内存,通过free释放内存。若通过malloc请求内存失败,则先尝试通过调用用户注册的处理函数尝试释放不再使用的内存,之后再次使用ma

2022-03-01 11:12:02 478

原创 Linux大页配置与使用

Linux大页配置与使用为何使用大页更大的内存页能够减少内存中的页表层级,可以降低页表的内存占用,也能降低从虚拟内存到物理内存转换的性能损耗。更大的内存页可以有更高的TLB命中率。更大的内存页可以减少获取大内存的次数。配置大页/proc/sys/vm/nr_hugepages #indicates the current number of "persistent" huge pages in the kernel's huge page pool.#With support for m

2021-12-16 20:00:07 3274

原创 virsh配置安装虚拟机

virsh配置安装虚拟机安装所需软件:apt-get install qemu-kvmapt-get install qemuapt-get install libvirt-binapt-get install bridge-utilsapt-get install virt-managerapt-get install virt-viewer创建虚拟机镜像文件(相当于虚拟机磁盘文件):qemu-img create -f qcow2 mydisk-img.qcow2 20G创建虚拟

2021-12-16 14:50:31 2253

原创 简易协程库

协程本项目Github地址简介使用C++和x86汇编设计并实现了一个简易的有栈协程库。通过保存和恢复Callee Save寄存器的方式实现协程的切换。通过admin协程进行协程调度,每次协程调度都会先切换回admin,由admin选择下一个上台运行的协程。使用显示运行时打桩机制Hook常用的库函数例如read和accept函数等,改为使用非阻塞的方式调用,从而避免线程被挂起。从x86-64汇编开始Callee Save和Caller Save在x86-64体系结构中,寄存器可以分为两种:Call

2021-10-06 21:01:54 233

原创 pytorch手把手使用FasterRCNN进行目标检测

手把手使用FasterRCNN进行目标检测使用pytorch自带的预训练FasterRCNN目标检测模型进行目标检测,并把检测到的结果打印到原图片上。由于pytorch自带的FasterRCNN是使用COCO数据集进行预训练得到的,所以我们需要使用COCO的标签来匹配模型输出的结果。详细的注释都在代码里面了。import torchimport torchvisionfrom torchvision.models.detection.roi_heads import fastrcnn_loss

2021-10-06 20:49:13 5343 6

原创 Linux批量kill进程

Linux批量kill进程 ps -ef | grep something | awk '{print $2}' | xargs kill -9解释:ps -ef 打印所有进程信息| 管道,将上一个进程的输出输入下一个进程,下同grep something 筛选相关进程信息awk '{print $2}' 输出相关进程号xargs kill -9 用上一个进程的输入作为kill -9的参数或者ps

2021-10-04 17:09:34 84

原创 RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the

RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same出现这个问题是因为输入模型的tensor加载在cpu中,而模型却加载在cuda上。解决方法:将输入tensor加载到cuda中,或者把模型加载到cpudevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")mod

2021-10-03 11:56:57 1647 1

原创 Linux查看磁盘空间

Linux查看磁盘空间查看磁盘空间:df -h查看当前目录所占空间:du -sh查看当前目录下各个文件夹所占的空间:du -sh *查看某个文件夹所占空间:du -sh filepath

2021-10-02 17:11:25 193

原创 TCP相关知识点

TCP多路分解和多路复用将运输层报文段中的数据交付到正确的套接字的工作成为多路分解。在源主机从不同的套接字中收集数据块,并为每个数据块封装上首部信息(这将在以后用于分解)从而生成报文段,然后将报文段传递到网络层,所有这些工作称为多路复用。可靠数据传输原理停-等协议回退N步协议基序号base定义为最早的未确认分组的序号,将下一个序号nextseq定义为最小的未使用序号(即下一个待发分组的序号),则可将序号范围分割成4段。在[0, base-1]段内的序号对应于已经发送并被确认的分组。[base,

2021-07-15 11:32:14 408

原创 C/C++内存对齐问题

为何需要内存对齐?尽管内存以字节为单位,但是大部分处理器并不是按照字节块来存取内存的。它一般会以双字节、四字节、8字节、16字节甚至32字节为单位来存取内存,这些存储单位被称为内存存取粒度。从Cache角度看从上图可以看出,一个cache line保存了2^b个字节。如果没有内存对齐规则,数据可以随意存放,那么可能导致一个变量被分隔在两个cache line中,这样处理器就需要读取两行cache line然后再将其合并成一个变量。从物理内存角度看从上图中可以看出内存模块由8个8Mx8的DRA

2021-07-12 17:05:09 271 1

原创 Make命令与Makefile文件

Make命令使用Make命令只会在必要时重新编译所有受改动影响的源文件。而不会因为只改动了一个文件而重新编译整个项目。Make命令不仅仅用于编译程序,无论何时,当需要通过多个输入文件来生成输出文件时,你都可以利用它来完成任务,它的其他用法还包括文档处理。make命令选项和参数:-k 让make命令在发现错误时仍然继续执行下去,而不是在检测到第一个错误时就停止。-n 让make命令输出将要执行的操作步骤,而不真正执行这些操作。-f 告诉make命令将哪一个文件作为makefile文件。若没有

2021-07-08 14:34:48 1144

原创 C++万能引用与完美转发

C++万能引用与完美转发什么是万能引用如果函数模板形参具备T&&型别,并且T的型别系推导而来,或如果对象使用auto&&声明其型别,则该形参或对象就是个万能引用。万能引用首先是一个引用,它既可以绑定到左值引用,也可以绑定到右值引用。先看个例子:extern "C"{ int printf(const char * format, ...);}template<typename T>void func(T& val){

2021-06-26 16:18:31 409

原创 C++ lambda表达式的使用

C++ lambda表达式的使用lambda语法如下:[函数对象参数](操作符重载函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}[函数对象参数]函数对象是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些定义lambda表达式时,作用域内可见的局部变量。这部分不可省略。[] 没有任何函数对象参数。[=] 函数体可以使用可见的所有局部变量,按值传递。[&] 函数体可以使用可见的所有局部变量,按引用传递。[this] 函

2021-06-26 10:10:28 217

原创 c++中bind的参数传递方式

c++中bind的参数传递方式在bind函数中的参数传递方式看代码:extern "C"{ int printf(const char * format, ...);}#include<functional>void func(int val){ printf("Val = %d\n", val); return;}int main(){ int a = 520; auto callfunc = std::bind(func, a);

2021-06-25 19:16:49 1551

原创 vector容器初始化{}和()的区别

vector容器初始化{}和()的区别看代码:extern "C"{ int printf(const char * format, ...);}#include<vector>int main(){ std::vector<int> vec1{10, 20}; for(int i=0;i<vec1.size();i++){ printf("%d ", vec1[i]); } printf("\n");

2021-06-25 18:37:38 367

原创 C++在priority_queue中自定义比较函数

C++在priority_queue中自定义比较函数方法一可调用函数操作符的对象struct Node{ int val;};struct cmp{ bool operator()(const Node &a, const Node &b){ return a.val > b.val; }}priority_queue<Node, vector<Node>, cmp> q;方法二重载比较运算符s

2021-06-25 16:09:07 1303

原创 C++类内存布局(虚函数与虚继承)

C++类内存布局单继承class Base{ int x, y;};class Derive: public Base{ int z;};可以看到,在Derive类中,Base类的成员被放在了前面。多继承class Base1{ int x, y;};class Base2{ int a, b;};class Derive: public Base1, public Base2{ int z;};对于多继承而言,一般是按照

2021-06-01 10:34:08 503 3

原创 C++符号修饰Name-mangling

C++符号修饰C语言符号修饰在上古时期,编译器编译源代码产生目标文件时,符号名与相应的变量和函数的名字是一样的。比如一个汇编源代码里面包含一个函数foo,那么汇编器将其编译成目标文件后,foo在目标文件中的相应符号名也是foo。当后来UNIX平台和C语言发明是,已经存在了相当多的使用汇编编写的库和目标文件。这样就产生了一个问题,那就是如果一个C程序要使用这些库的话,C语言中不可以使用这些库中定义的函数和变量的名字作为符号名,否则会与现有的目标文件冲突。为了防止类似的符号名冲突,UNIX下的C语言就规定

2021-05-29 16:54:27 908 1

原创 C++程序动态链接

C++程序动态链接关于动态链接的原理,可以先看下这篇先看代码://simpleApp.cppint foo(int a, int b);int main(){ int a = 0; int b = 1; int c; c = foo(a, b); return c;}[root@xxxx] g++ -c simpleApp.cpp #生成.o文件[root@xxxx] g++ -o simpleApp simpleAp

2021-05-29 16:27:22 1133 2

原创 C++程序静态链接

C++程序静态链接先看代码://simpleApp.cppint foo(int a, int b);int main(){ int a = 0; int b = 1; int c; c = foo(a, b); return c;}[root@xxxx] g++ -c simpleApp.cpp #生成.o文件[root@xxxx] g++ -o simpleApp simpleApp.cpp #生成可执行文

2021-05-29 16:24:14 345 1

原创 C++全局对象的构造与析构

C++全局对象构造与析构先上代码://simpleClass.cppclass A{ int val;public: A(int n){ val = n; } ~A(){ val = 0; }};A a1(1);int main(){ A a2(2); return 0;}抛出问题:局部对象a2和全局对象a1分别在何处调用构造函数和析构函数?将上述cpp文件编译成可一致性文件:g++ -o

2021-05-28 18:20:32 1889 5

原创 C++移动语义

C++移动语义可拷贝和可移动的概念在C++编程中,有的类是可以拷贝的,比如属性值、状态值等等,这些可以调用拷贝构造函数去拷贝。但有些类的对象是独一无二的,或者类的资源是独一无二的,比如申请的内存空间、IO buffer等等,他们不可以拷贝,但是可以把资源的所有权交出给新的对象,称为可以移动。C++11最重要的一个改进之一就是引入了move语义,这样在一些对象构造时就可以获取到已有的资源而不需要通过调用拷贝构造函数,申请新的内存,这样移动而非拷贝将会大幅度提升性能。例如有些右值即将析构,这时我们用移动构

2021-05-21 19:51:27 712 3

原创 C++对象初始化与重载赋值运算符

C++对象初始化与重载赋值运算符对象初始化如下代码:#include<iostream>#include<vector>#include<cstring>using namespace std;class A{public: int val; char *buffer; A(int n){ val = n; buffer = new char[val]; cout<<"A

2021-05-21 19:50:47 285

原创 【小技巧】爆栈?栈的大小不够用怎么办?

爆栈?栈的大小不够用怎么办?Linux系统栈帧大小我们先从一段代码开始:#include<stdio.h>const int N = 4*1024*1024;int func(){ int buf[N]; printf("%d\n", N); printf("%d\n", sizeof(buf)); return 0;}编译执行上述代码,显而易见,报Segment Fault错误。用如下指令查看系统栈帧的最大size:ulimit -s

2020-11-29 16:06:22 3149

原创 Linux进程中的RSS和VSZ

Linux进程中的RSS和VSZ64位Linux系统中虚拟内存空间大小我们都知道32位系统的虚拟内存空间大小是2^32B,也就是4GB。但是,64位系统的虚拟内存空间的大小并不是2^64B,而是2^48B,也就是256TB。而64位系统支持的物理内存大小最高为2^46B,也就是64TB(这当然远超出了目前我们日常使用的物理内存的规格)。查看Linux系统支持的物理内存和虚拟内存大小的方法:cat /proc/cpuinfo | grep 'address sizes'RSSRSS is th

2020-11-28 10:45:53 2993 2

原创 二分搜索之lower_search和upper_search以及lower_bound和upper_bound

lower_search和upper_search以及lower_bound和upper_bound在已经排好序的序列中,使用log(n)复杂度的方法寻找出某个数的下标位置。示例:vector = [1,2,2,2,3,4,4,5,6] target = 2lower_search若序列中存在target,则返回其最小的下标,否则返回-1。void lower_search(vector<int> &nums, int target){ int left = 0;

2020-10-29 20:24:49 194

原创 C++STL容器扩容的效率问题

C++STL容器扩容的效率问题这里以STL中的vector容器举个例子,vector初始化时的容量是比较小的(在不使用reserve的情况下),当需要扩容时,需要把之前所有的元素都通过拷贝构造函数的方式拷贝到新的内存空间中,这样的效率是比较低的。看下面这段代码:#include<iostream>#include<vector>using namespace std;class A{public: int val; A(int n){

2020-10-14 18:52:58 511

原创 C++关于默认构造函数和无参构造函数

C++关于默认构造函数和无参构造函数默认构造函数在不提供任何构造函数的情况下,编译器给出一个不带参数的,不包含代码的构造函数。#include<iostream>using namespace std;class A{public: int val;};int main(){ A a; //这里调用的是默认构造函数 cout<<a.val<<endl; return 0;}当已经提供了显式的构造函数,例如:

2020-10-14 17:42:53 7439 4

原创 C++STL中resize()和reserve()的区别

C++STL中resize()和reserve()的区别简而言之,resize()会构造出新的元素,而reserve()只是为元素预留出空间而已。resize()#include<iostream>#include<vector>using namespace std;class A{public: int val;};int main(){ vector<A> vec; vec.resize(10); return

2020-10-14 17:41:34 769

原创 C++STL中emplace_back()和push_back()的区别

emplace_back()和push_back()的区别先来看几个例子:#include<iostream>using namespace std;class A{public: A(){ cout<<"A construct function."<<endl; } ~A(){ cout<<"A destory function."<<endl; }};int

2020-10-14 14:41:33 3657 2

原创 《深入理解计算机系统》bomb lab第五个字符串

《深入理解计算机系统》bomb lab第五个字符串首先看下phase_5的反汇编代码 0x0000000000401062 <+0>: push rbx 0x0000000000401063 <+1>: sub rsp,0x20 0x0000000000401067 <+5>: mov rbx,rdi 0x000000000040106a <+8>: mov rax,QWORD P

2020-09-29 14:47:54 212

原创 深度学习(四)之反向传播与梯度下降(公式推导)

深度学习之反向传播与梯度下降  有了前馈神经网络,又有了损失函数,就可以使用反向传播算法来更新神经网络中的参数,使得网络的输出尽可能地接近真实值。反向传播算法就是通过链式法则,从最后面的损失函数开始到前面的每一层网络都对参数进行求导,得到梯度之后再使用梯度下降算法更新参数,使得模型的损失函数的输出尽可能小,本质上是损失函数的最优化问题。假设神经网络的输入值为x,输出值为y,激活函数为f,参数为W,偏置量为b,损失函数为L。则第n层的输入值为x(n)x^{(n)}x(n) 输出值为y(n)y^{(n)}y(

2020-09-15 23:45:02 1740

原创 深度学习(三)之损失函数

深度学习之损失函数L1范数损失函数  多层感知机可将单层感知机学习到的简单概念进一步整合学习得到复杂的概念,每一层都整合学习上一层输出的较简单的概念,越深的网络能学习到的概念就越高层越复杂。每一层整合的概念方式就是每一个输入值和对应参数的乘积之和,再通过激活函数。  而深度神经网络的学习过程就是不断地更新这些参数,直到得到最优的参数。那么什么样的参数才算是最优的权值呢?其实就是能使神经网络的输出值尽可能地接近真实值的参数,也就是要使得输出值与真实值之间的误差尽可能地小。通常定义一个损失函数来表示输出值

2020-09-15 23:25:36 1769

原创 深度学习(一)之感知机与神经网络

深度学习之感知机与神经网络深度学习概述  人工智能这个概念并不是一个新潮的概念,早在人类尚未制造出第一台计算机之前,人们就已经开始思考计算机是否可以变得智能。在人工智能发展的早期,那些对于计算机来说很简单,但对于人类智力来说却相对困难的问题得到解决,例如一些复杂的计算繁重的但是可以通过一系列形式化的数学规则来描述的问题。IBM的深蓝国际象棋程序在1997年打败了世界冠军,而国际象棋可以简短地使用一个完全形式化的规则列表来表示,计算机只需要按照规则来搜索出最佳策略即可。  人工智能技术的真正难点在于如何

2020-09-15 23:12:39 932

原创 深度学习(二)之激活函数

深度学习之激活函数  感知机模型中的函数f是非线性的,称为激活函数,激活函数的作用是将输出变为非线性的,这是因为现实世界中大部分数据都是非线性的。比较常用的激活函数有Sigmoid、Tanh和Relu[28]函数。  Sigmoid函数是早期神经网络经常选用的激活函数,其数学表达式为:  Sigmoid函数图像如下:  从图像上可以看出,Sigmoid函数取值范围为(0,1),输入非常小时输出为0,输入非常大时输出为1。其函数曲线比较平滑,易于求导,缺点是反向传播求梯度时涉及到除法计算,而且很容

2020-09-15 23:12:01 360

原创 深度学习计算机视觉发展简述

深度学习计算机视觉发展简述  1995年诞生的LeNet5[14]网络是最早的卷积神经网络之一,也是现在很多深度神经网络架构的起点。LeNet5利用卷积、参数共享、池化等操作提取图像特征,再利用全连接神经网络进行分类。受限于当时计算机算力不足的问题,卷积神经网络无法发挥出其强大的威力。  2012年Alex等人提出AlexNet[15]网络在ImageNet[16]大赛上以15.3%的错误率绝对优势夺得当年的冠军。利用深度卷积神经网络进行图片分类成为了最受欢迎的技术。和LeNet相比,AlexNet使用

2020-09-15 22:59:04 941

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除