Neo's Blog

不抽象就无法深入思考
不还原就看不到本来面目!

0%

0. 云游戏场景描述

云游戏指在云服务器端运行的游戏,不仅需要将渲染后的游戏画面推送到终端,还需要将终端操作的指令传输到云端服务器进行处理。这种实时交互的需求,使得云游戏对网络时延有较高的要求,需要在尽量靠近用户终端的位置提供服务。

Read more »

0. 实时音视频场景描述

实时音视频业务(例如互动直播)场景下,业务对网络时延具有较高的要求。为保证优质的业务体验,需实现低网络时延。如果用户所在的地理位置与中心机房的物理距离过远,网络时延将会明显增加,影响业务体验。

Read more »

CPU寄存器

在用途方面,他们有各自默认的用途:

  • Eax用来保存所有API函数的返回值。寄存器AX和AL通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。累加器可用于乘、除、输入/输出等操作,它们的使用频率很高;
  • 寄存器BX称为基地址寄存器(Base Register)。它可作为存储器指针来使用;
  • 寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时,要用它来控制循环次数;在位操作中,当移多位时,要用CL来指明移位的位数;
  • 寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址。

寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),

它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。

那么ESP和EBP指的分别是什么呢?

  • ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
  • EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。

对于64位CPU,EAX —-> RAX

CPU指令的执行

一个基本的CPU执行计算的过程如下:

  1. 程序以及数据被加载到主内存
  2. 指令和数据被加载到CPU的高速缓存
  3. CPU执行指令,把结果写到高速缓存
  4. 高速缓存中的数据写回主内存

一次函数调用

栈的增长方向:向下增长,ESP越来愈小、ESP比EBP小

一个函数执行步骤:

  1. 函数参数压入stack中
    push p1
    push p2
  2. CPU自己把返回地址压入stack中
    push eip
  3. CPU自己跳转到新的函数地址(call func),开始执行(先保存EBP,然后让EBP指向当前ESP)
    push ebp 保存老函数的EBP到新的stack中
    mov esp => ebp 让ebp保存新函数的stack base
  4. 分配局部变量
    sub esp 100 分配100字节的局部变量
  5. 局部变量赋值与访问
    通过ebp - $Offset$ 来访问局部变量
  6. 访问参数
    通过ebp + $Offset$ 来访问参数
  7. 函数返回
    add esp 100
    mov ebp => esp
    注意:上面这一句应该是重复的,理论上只要对esp进行了完成逆操作,esp应该等于ebp了。是不需要额外通过ebp来还原的;当然如果要通过ebp来还原,也就不需要去显示操作esp了。
    pop ebp 还原ebp
    ret(pop eip)
  8. 将压入的参数POP出来
    pop p2
    pop p1

指令集

所谓指令集,是CPU中用来计算和控制计算机系统的一套指令的集合。指令的强弱是CPU的重要指标,指令集是提高微处理器效率的最有效工具之一。

CPU依靠指令来计算和控制系统,每款CPU在设计时就规定了一系列与其硬件电路相配合的指令系统。与其他硬件电路相配合,决定的是这一款CPU的生态系统。因此,指令集搭建的是一个桥梁,是软硬件之间沟通的桥梁,简单来说,软件通过指令集和硬件讲话。因此,指令集对形成生态至关重要,从这个意义上讲,不同的CPU指令集,决定了这款CPU设计的复杂程度。

从现阶段的主流体系结构讲,指令集可分为复杂指令集(CISC, complex instruction set computer)和精简指令集(RISC, reduced instruction set computer)两部分。简单来讲,RISC功能简洁,代表着简洁的CPU设计,CISC功能完备,代表着复杂的CPU设计。
这里引用步日欣老师文章中的一段话:

CPU的指令,就如同盖房子的砖,如果都是小块的标准砖头,也能盖起各种不同的房子,这就是RISC;
如果除了标准砖头,还设计了很多的砖瓦结构件,适用于拐角、吊梁等,这就是CISC。
不同的模式,都能盖起房子,但是效率却大不一样,RISC的标准砖头,小平房可以盖,
摩天大楼也可以盖,底层的原材料很简单,都是标准化的砖头;
CISC的各种复杂的结构件,对于盖一种房子的时候效率确实高,吊起结构件随便一拼装就ok,
但是如果要盖的房子种类多了,就需要定义更多更复杂的结构件,结构件的管理就会越来越复杂,
而且在建设某种常见建筑的时候,大部分特殊的结构架是闲置不用的,大大影响了施工效率。
基于CISC模式下的CPU设计,在各种新需求下,堆叠的功能越来越复杂,芯片设计难度也越来越高,效率低下,
因此就出现了RISC精简指令集的概念。

对比CISC和RISC

CISC的指令能力强,单多数指令使用率低却增加了CPU的复杂度,指令是可变长格式;RISC的指令大部分为单周期指令,指令长度固定,操作寄存器,只有Load/Store操作内存

CISC支持多种寻址方式;RISC支持方式少

CISC通过微程序控制技术实现;RISC增加了通用寄存器,硬布线逻辑控制为主,是和采用流水线

CISC的研制周期长

RISC优化编译,有效支持高级语言

大白话就是:

CISC架构,性能好,但是耗电多,电压高。主要用于桌面服务。

RISC架构:耗电少,电压低,但是单核性能比不上CISC架构,主要用于嵌入式开发,或者移动设备开发。

CPU架构

  1. ARM架构,过去称作进阶精简指令集机器(Advanced RISC Machine,更早称作:Acorn RISC Machine),是一个32位精简指令集(RISC)处理器架构

  2. x86或80x86是英代尔Intel首先开发制造的一种微处理器体系结构的泛称。x86架构是重要地可变指令长度的CISC(复杂指令集电脑,Complex Instruction Set Computer)。

  3. MIPS是世界上很流行的一种RISC处理器。MIPS的意思是“无内部互锁流水级的微处理器”(Microprocessor without interlockedpipedstages)

  4. PowerPC 是一种精简指令集(RISC)架构的中央处理器(CPU),其基本的设计源自IBM(国际商用机器公司)的IBMPowerPC 601 微处理器POWER(PerformanceOptimized With Enhanced RISC

intel,amd和arm的关系

Intel 与 AMD是两个公司,amd 与 arm 又是同一个公司(AMD)的两款产品

Intel与AMD共同采用x86架构,都采用CICS指令集,一般用于桌面应用;

而arm 采用 ARM架构,采用RICS指令集,例如家用游戏机、平板、手机等会采用arm CPU

可以说,AMD CPU是 AMD公司为对抗Intel公司的Intel CPU推出的第一代产品;

而 ARM CPU 是AMD公司为了对抗Intel公司的Intel CPU推出的第二代产品,

co 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

struct co_ctx{
void* regs[14]; //用于保存或者设定特定寄存器
size_t ss_size; //栈帧区域大小
char* ss_sp; // 协程栈帧内存区域,这个区域一般在堆上分配
}

co_make (co_ctx* co, func* p, p1, p2) {
使用p, p1, p2把co填充起来
co.ss_sp都是分配在堆上
co的EIP与ESP需要被单独赋值
}
co_swap(){
主要要保存当前寄存器到要swap_out的co_ctx中
将要swap_in的co_ctx设置到寄存器中
}

具体参考:https://vinsflyfish.github.io/posts/thinking-in-libco/

0. 题目

给你一棵二叉树,它的根为 root
请你删除 1 条边,使二叉树分裂成两棵子树
且它们子树和的乘积尽可能大

由于答案可能会很大
请你将结果对 10^9 + 7 取模后再返回

Read more »

0. 函数调用约定

名称 谁来清理入栈参数 参数压栈顺序 函数名转换规则
__stdcall 被调用函数在返回前清理入栈参数 参数自右向左压栈 C语言时,_function@number,number为参数的字节数;C++编译时函数名的转换:?function@@YG**@Z或者?function@@YG*XZ;若函数有参数,以@Z结束;若函数无参数,则以Z结束
__cdecl 调用函数在返回后清理入栈参数 参数自右向左压栈 _function,其中function为函数名;C++编译时函数名的转换:同__stdcall,把YG改为YA
__fastcall 被调用函数在返回前清理入栈参数 使用ECX传递第一个参数,EDX传递第二个参数,其余参数自右向左压栈 C编译时函数名的转换:@function@number;C++编译时函数名的转换:同__stdcall,把YG改为YI
__pascal 被调用函数在返回前清理入栈参数 参数自左向右压栈 较为复杂,参加pascal文档
Read more »

0. The Two Egg Problem

You are given two eggs, and access to a 100-storey building. Both eggs are identical. The aim is to find out the highest floor from which an egg will not break when dropped out of a window from that floor. If an egg is dropped and does not break, it is undamaged and can be dropped again. However, once an egg is broken, that’s it for that egg.

If an egg breaks when dropped from floor n, then it would also have broken from any floor above that. If an egg survives a fall, then it will survive any fall shorter than that.

The question is: What strategy should you adopt to minimize the number egg drops it takes to find the solution?. (And what is the worst case for the number of drops it will take?)

Read more »

0. 背景介绍,把人吸引过来

之前总有一些年轻人问我,我应该了解哪些知识才能像某某某那么牛B。
这句话的意思其实就是:他们特别困惑,想知道一个后端程序员的知识体系,想知道从哪开始学起。

关于这个问题,琢磨了好久,我不想简单的一句话就敷衍过去了,这个问题我要深思熟虑去回答。
因为如果 10 年前有人告诉我这个问题的答案,现在的我将少走很多的弯路,技术水平也会更上一层楼。

简单说一下全文的结构,全文一共分为四大部分。第一部分,主要从硬件、操作系统、网络、数据结构&算法等几个方面跟大家聊一下计算机科学相关的基础知识。第二部分,讲一下设计一款高性能的服务框架,应该从哪些方面着手;第三部分,讲一下平常工作中使用最频繁的知识-数据库、缓存以及一些相关的经典问题;最后第四部分,讲述的侧重点从第二部分的微观转到相对宏观的内容,跟大家聊一下分布式系统、大型架构设计等相关知识。

引用古人的一句话,来开始我们的征程!

“路漫漫其修远兮,吾将上下而求索!”

Read more »

0. 背景介绍,把人吸引过来

image

积分中值定理、微分中值定理


泰勒公式

出发点:

用简单的熟悉的多项式来近似代替复杂的函数

易计算函数值,导数与积分仍是多项式

多项式由它的系数完全确定,其系数又由它在一点的函数值及其导数所确定。

image

阶数

阶乘:削弱高阶项的作用,让他晚一些起作用!

Read more »

0. 背景介绍,把人吸引过来

image

积分中值定理、微分中值定理


泰勒公式

出发点:

用简单的熟悉的多项式来近似代替复杂的函数

易计算函数值,导数与积分仍是多项式

多项式由它的系数完全确定,其系数又由它在一点的函数值及其导数所确定。

image

阶数

阶乘:削弱高阶项的作用,让他晚一些起作用!

Read more »

逻辑回归,是一种分类算法,而并非回归算法。

逻辑回归要解决的问题是,给你一组样本以及标签,你基于这些数据去训练你的模型。然后我再给你一个新的样本,你告诉我有多大概率的属于某一个分类【二分类问题,黑还是白】

$Y = \theta * X + \epsilon $

我们现在的目标是找到一组$\theta$可以让它乘以X之后尽可能的匹配Y

$\epsilon$为误差,服从均值为0,方差为$\mu^2$的正态分布

预测值与真实值之间有误差

学习的关键在于:确定什么样的参数最符合于你的目标

我们的目标是什么? 让误差项尽可能的小,接近于0,loss函数等于0

条件概率: 也服从正态分布。

对于某一个样本,要找到一个theta, 跟x组合之后,成为真实值y的可能性最大

Read more »