结构体成员变量的字节对齐
编译器版本(MinGW 及其衍生品,比如 TDM-GCC
可能不支持 #pragma pack(n), n>1,参见 mingw-and-packed-struct-alignment-using-c11)
12345❯ gcc --versiongcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0Copyright (C) 2021 Free Software Foundation, Inc.This is free software; see the source for copying conditions. There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
本文讨论的对齐属性
123#pragma pack(n)__attribute__((packed));__attribute__((aligned(8)));
完整验证代码见文末
在 Linux 环境下 char 占 字节,int 占 字节,sho ...
垃圾回收机制
垃圾回收(GC)
垃圾回收(Garbage
Collection),指的是对内存堆中长时间未使用的对象进行回收。
在Java中,垃圾回收通常是由JVM的GC线程自动完成的,开发者不需要手动实现。
如何定义垃圾
引用计数算法
引用计数算法(Reachability
Counting)是通过在对象头中分配一个空间来存储该对象被引用的次数。如果该对象被其它对象引用,则它的引用计数加,如果删除对该对象的引用,那么它的引用计数就减1,当该对象的引用计数为0时,那么该对象就会被回收。
引用计数算法是将垃圾回收分摊到整个应用程序的运行当中,而不是在进行垃圾收集时挂起整个应用的运行,直到对堆中所有对象的处理都结束。因此,采用引用计数的垃圾收集不属于严格意义上的Stop-The-World的垃圾收集机制。
但是,现在JVM的垃圾回收机制是Stop-The-World的,考虑这个例子
123456789101112131415161718public class ReferenceCountingGC { public Object instance; public ReferenceCo ...
支持向量机
支持向量机是一种用于分类的算法。如果数据是线性可分的,只需要将直线放置在让点距离平面距离最大的位置,寻找这个最大间隔的过程叫做最优化;如果数据不是线性可分的,需要用核函数改变维度,用超平面做分类……
线性 SVM
如图,数据显然是线性可分的,这些将它们分类的直线称为
决策面,每个决策面对应一个线性分类器。但是将它们分开的直线显然不止一条。目前
和
的分类效果相同,但如果再增加一个点(在 和 之间),就会出现分类错误。
图中虚线的位置由决策面的方向和距离决策面最近的几个样本位置决定,虚线穿过的样本点称为
支持向量,中间的部分是分类间隔。具有最大间隔的决策面就是
SVM 要找的最优解。
数学建模
目标函数:希望使得什么指标最好,即分类间隔
优化对象:可以改变的影响因素,即决策面
优化对象(决策面)
在二维空间中,一条直线可以表示为
设其中 ,,
是这条直线的法向量,
是截距。把二维平面的直线推广到
维空间,就得到了超平面方程
此时的 ,。
目标函数(分类间隔)
分类间隔的大小是支持向量的样本点到决策面距离的二倍,二维平面中,点到直线的距离公式是
推广到多维
分类 ...
反向传播算法
当网络给出预测之后,需要根据预测值与实际标签的差异调整网络中的权重和偏置,以便模型在将来能够更好地预测。这个调整过程称为反向传播(误差计算
→ 梯度计算 → 参数更新)。
神经网络的结构
假设一共有 层网络,激活函数为
, 表示未激活的状态, 表示激活后的状态。
损失函数为
损失函数对
的偏导数为
基本方程
为了实现参数更新,我们需要计算 和 ,
其中涉及到激活函数即 ,为了简化计算,先定义一个中间变量
:
输出层的
推广到 ,得到
对于 层,
其中 中 影响了图中红线所示部分
同理,可以得到
对于任意第 层,
下面计算 和 ,
算法流程
输入数据
前向传播
反向传播误差
梯度下降,更新参数
代码实现
1234567891011121314151617181920212223242526272829303132333435def backprop(self, x, y): """Return a tuple ``(nabla_b, nabla_w)`` representing the nablaient ...
信息论基础
熵和互信息的关系
相对熵(KL 距离)
相对熵衡量的是同一事件空间中两个概率分布的差异,不是距离。
在同一事件空间中,概率分布
对应的每个事件如果用
编码,平均每个基本事件编码长度增加了多少比特。
用 表示 距离,计算公式为
两分布相似度越高,相对熵越小。
非负性(由吉布斯不等式可证)
若 ,则
,当且仅当 时取等
不满足对称性(交叉熵
相对熵)
不满足三角不等式
数据处理不等式
如果 的条件分布仅依赖 的分布,与 条件独立,随机变量 构成马尔科夫链,满足
记为 ,则 。如果 ,则
.
数据越传损失的越多;数据
的函数不会增加关于 的信息量~
如果 ,则 。
通过观察 , 与 的依赖会降低~
Fano 不等式
(+﹏+)~晕,待续……
渐进均分性
收敛
收敛:图像逐渐趋近于某条横线
,当 时,满足
,即 ,记作
几乎确定收敛:图像逐渐趋近于某条横线,但是有几个点各色
,当 时,满足
,即
依概率收敛:
,当
时,满足 ,即 ,记作 .
大数定理
强大数定理: 一直向 靠近
弱大数定理: 向 ...
TCP的流量控制与拥塞控制
流量控制(滑动窗口)
TCP 通过 滑动窗口机制
防止接收方处理数据的速度跟不上发送方,避免随着时间推移,数据自然溢出接收方的缓冲区。
发送端
发送方会建立自己的滑动窗口,按三个标准划分:是否发送、是否收到
ACK、是否在接收方通告处理范围内。
已经发送并且收到 ACK
的部分,已经成功发送,不需要在缓冲区保留;
已经发送但未收到 ACK;
可用窗口:还没有发送,但是还在接收方窗口处理范围内(第二、三部分为整个
发送窗口);
可用窗口大小=SND.WND+SND.UNA-SND.NXT
SND.WND:发送窗口,32-51
SND.UNA:指针,指向已发送未确认的字节,如上图
SND.UNA=32
SND.NXT:可用窗口的第一个字节,如上图
SND.NXT=46
需要发送,但是超过接收方窗口范围的部分。在没有收到新的
ACK
之前,发送方不会发送这些数据,通过这个限制,发送的数据就不会超过接收方缓冲区;
如果 ACK
在网络传输中丢包,发送端就不会感知到接收端窗口的变化,发送方一直没有收到
ACK,随着数据不断发送,可用窗口会被占满,发送方认为接收端处于零窗口状态 ...
介质访问协议
Aloha
Pure
Aloha:如果某个主体想发送一个帧,直接发送;如果产生冲突,冲突帧无效,之后重传;
Slotted
Aloha:将发送时间分槽,按时间槽发送帧,降低冲突;
随机介质访问方式
MA((Multiple Access):多路访问
CSMA(Carrier Sense Multiple
Access):载波监听多路访问
CSMA/CD(…Collision Detection):……冲突检测
载波监听多路访问(CSMA)
CSMA
协议是在ALOHA协议基础上,多了一个载波监听装置的改进协议。
为了降低冲突,每个站点在发送前先侦听共用信道,发现信道空闲后再发送。根据侦听方式和侦听到信道忙后的处理方式不同,CSMA
分为三种
1-坚持 CSMA
一个结点要发送数据时,首先侦听信道;如果信道空闲,那么立即发送数据;如果信道忙,那么等待,同时继续侦听直至信道空闲;如果发生冲突,随机等待一段时间后,再重新开始侦听信道。
产生冲突情况:
传播延迟:结点 A 开始发送数据时,结点 B
也正好有数据要发送,但这时结点 A 发出数据的信号还未到达结点 B,结点 B
侦听到 ...
CPU流水线技术
不同指令的执行时间不同,如果让所有指令都能在一个时钟周期内完成,那就我们只能将时钟周期设置为指令执行时间的最大值,这样最大组合逻辑延迟决定了
CPU 频率上限,一般 CPU 的性能与 CPU
频率呈正相关,因此,降低组合逻辑的延迟能够提升 CPU 性能。方法包括
划分较小的组合逻辑 和 流水线设计。
CPU 的流水线设计
取指令(IF):从存储器取指令
指令译码(ID):产生指令执行的控制信号和操作数
执行(EX):执行部件根据指令完成运算
访存(MEM):从存储器读取或写入数据
写回(WB):将运算结果写回存储器
CPU
提供了最长的公共流水线,但并非所有指令都能利用各个阶段,而且实际上流水线划分不一定均匀,考虑将操作时间长的指令深度划分……虽然流水线设计不能减少单指令执行的“延时”,但是提高了
CPU 的吞吐率。
超长流水线的性能瓶颈
为了保持段间数据,需要设置
流水线寄存器,然后再下一个时钟周期交给下一流水线级处理,每增加一级流水线,就多一次写入寄存器的时间。
流水线冒险
将指令拆解为流水线并行执行,会遇到依赖阻塞问题,如果后续指令运行依赖前序指令的运行结果,那么后续指引 ...
高速缓存
计算机程序运行时遵循局部性原理:
时间局部性:程序中的某条指令被执行,不久后该条指令可能再次被执行;某数据被访问,不久后该数据可能再次被访问(保留一段时间,等到之后被访问)
指令循环执行
局部变量集中存储,被频繁访问
空间局部性:程序访问了某个存储单元,它附近的存储单元也可能被访问(将邻近单元内容调入,等待之后被访问)
指令顺序执行
数组
引入高速缓存
典型的存储器层次结构如下图
CPU
设计的目的是实现高速计算,存储器设计的目的是实现大容量存储,两种器件需要分离。为了获得存取时间和存储容量的折中(tradeoff),弥补
CPU 与内存的性能差异,把 CPU 性能的提升利用起来,在 CPU
内部引入了高速缓存。从 CPU Cache 被加入到现有的 CPU
开始,内存中的指令、数据会被加载到 L1-L3 中,而不是 CPU 问内存去拿,其中
L1-L3 指由 SRAM(static RAM)组成的物理芯片。
运行程序的主要事件花在了将对应的数据从内存中读取出来,加载到 CPU
Cache 中,读取的单位称作 Cache Line(缓存块),大小通常是 .
...
多天线技术
单发射天线单接收天线之间的信道容量受限于香农公式,
要想在相同频谱带宽下进一步提高信道容量,需要采用多天线技术。
MIMO 信道建模
考虑一种极端情况,使用
对天线发送和接收,并且每对收发天线和其它天线离得足够远(即 Tx1 与 Tx2
足够远,Rx1 与 Rx2 足够远……)几对天线之间互不相干,那么容量就可以提高
倍。实际上,受限于天线的尺寸,两对天线的距离不可能足够远,而且终端尺寸很小,天线间的距离也就很小。
以双入双出的系统为例,其中 为信道增益, 为发送的基带数据, 为接收的基带数据(用复数形式表示为
数据)那么四条传输信道的信道增益如下表
接收-发射天线
信道增益
Rx1-Tx1
Rx1-Tx2
Rx2-Tx1
Rx2-Tx2
假设两个发射天线发出的基带数据分别为 和 ,那么接收端接收到的基带数据为
输入和输出基带数据构成矩阵 和
,信道增益构成矩阵 ,则有 1
天线间距非常大
天线间距足够大,相当于用射频电缆将 对收发天线直连起来,让接收天线 n
只能接收来自于发射天线 n 的信号,即
在已知输出基带数据和信道 ...