自然语言处理
自然语言处理发展综述
语言的出现是为了人与人之间的通信。英文字母或者中文的笔划实际上是信息编码的不同单位,任何一种语言都是一种编码方式,而语言的语法规则就是编码的算法。而人类研究计算机对自然语言的处理经过60多年的发展过程,大致分为两个阶段,第一个阶段(20世纪50-70年代)没有什么实质性进展,基本上是仿照人类对语言的认知,对自然语言进行句法分析和语义分析。第二个阶段转而用统计的方法才取得了实质性突破,并得到广泛应用。
语言的出现是为了人与人之间的通信。英文字母或者中文的笔划实际上是信息编码的不同单位,任何一种语言都是一种编码方式,而语言的语法规则就是编码的算法。而人类研究计算机对自然语言的处理经过60多年的发展过程,大致分为两个阶段,第一个阶段(20世纪50-70年代)没有什么实质性进展,基本上是仿照人类对语言的认知,对自然语言进行句法分析和语义分析。第二个阶段转而用统计的方法才取得了实质性突破,并得到广泛应用。
usb驱动分为主机测设备驱动UHC和从机测设备驱动UDC。其中Gadget(意为小器件)就是从机测驱动,包含各种usb外设驱动,常见的有usb声卡驱动、usb网卡驱动、usb串口驱动、u盘、usb鼠标键盘等。其驱动层次如下图所示:
EP0 | EP In | EP Out | |
---|---|---|---|
ADB | 1 | 1(bulk) | 1(bulk) |
UAC | 1 | 1(isoc) | 1(isoc) |
UAC FU | 1 | 1(int) | 0 |
UAC Async | 1 | 1(int) | 0 |
HID | 1 | 1(int) | 1(int) |
MTP | 1 | 1(bulk) | 1(bulk) |
RNDIS/ACM(CDC) | 1 | 2(int + bulk) | 1(bulk) |
我们A4/A5拥有的EP资源为EP0 + 3对EP(3个EP In + 3个EP Out),A1 拥有的资源为EP0 + 5对EP(5个EP In + 5个EP Out)。同时开启的功能占用EP资源数不能超过芯片支持的EP数。
高中时期真的很爱数学,虽然老师老是骂我不做作业,可是我真的有在努力的,只是不喜欢做题而已。高中三年我的数学课本上一直存在两段公式,一是一元三次方程的判别式和一元四次方程降阶的公式。记得当时一元三次方程用了一两个月的时间才推导出来的,其解法主要也是变量代换。其实即便拥有现代知识的我们去推导三次方程也需要花些时间的,可以先考虑非一般式的三次方程,比如没有二次项或者没有一次项,形如
而四次方程的研究我连续研究了2个多月的晚自习也毫无头绪,完全没辙,无奈最终只能放弃,当时还很受挫,原本还做着春秋大梦想着找到所有高次方程的通解公式。可是直到一天我在新华书店看到一本书叫《人类在数学上的发现》里面提到四次方程曾经让无数数学家都束手无策(心里突然释怀了,当时还不会上网,不懂得去网上查找资料)最后是费拉里给出了解决方案,而我将这段公式从高一的数学课本抄写到高三的数学课本中(因为实在不好解,很繁杂记不住只得抄录)。于是今天打算整理下高次方程背后的故事。
太阳(点A)照射于木星(点B)会产生阴影(范围从木卫一轨道的点C至点D)。从地球观察,当木卫一蚀发生之时(点C),木卫一会突然消失,运行进入木星阴影,称这现象为“消踪”;当木卫一蚀结束之时(点D),木卫一会突然出现,运行离开木星阴影,称这现象为“现踪”。
地球的公转轨道包含了点E、F、G、H、L、K。在任意一次木卫一蚀里,消踪与现踪不能够从地球都观察得到,因为其中一种现象必会被木星掩蔽。在冲日点(点H,地球在太阳与木星连线之间),消踪与现踪都会被木星掩蔽。在地球位置点L、K都可以观察到木卫一现踪(点D)。由于点L比点K接近点D,光波需要更多传播时间才能抵达点K。类似地,在地球位置点F、G都可以观察到木卫一消踪(点C)。由于点G比点F接近点C,光波需要较少传播时间才能抵达点G。
由于光线从D点到L和到K的距离不同导致在这两个点观察到的木卫一蚀时间上存在差异,罗默就利用这个时间差以及L与K之间的距离估算出了光速,当然罗默测的光速比实际慢了26%,这是由于当时对木星的轨道根数的错误造成的误差导致的。天文学家通过对天体的观察就推算出了光速,确实非常了不起。
我为什么会写这篇文章呢?高中时期读过几本对我影响非常大的书籍,其中一本是关于光的本质之争的书籍被我遗失了,之后也再没找到,最近在网络上搜集相关资料重新整理一下。当时读的时候关于光的波粒二象性相关实验对我触动很大,尤其那个非常恐怖的双缝干涉实验以及之后引出的一系列问题。
代码流程都是类似的找到sound/usb/pcm.c文件里的struct snd_pcm_ops 结构体,相关回调都在这里:
1 | static const struct snd_pcm_ops snd_usb_playback_ops = { |
主要关注下snd_usb_substream_playback_trigger函数,收到SNDRV_PCM_TRIGGER_START消息后会调用start_endpoints(subs);将usb 端点启动,然后注册端点操作函数指针,主要有两个:prepare_data_urb 和retire_data_urb 其中
以下是之前通过打印时间戳的方式统计的数据,实际存在一些偏差。
这个过程包括Attached、Powered、Reset(进入Default状态)、Set Address(进入Address状态)。然后会进入config阶段,如下:
1 | 描述符的类型有: |
这里0x0100,表示设备描述符,索引为0
在debug期间我们可以给栈空间赋值为一个特定值,比如0x5a,然后在每次中断中检查该值是否发生变化,来检测操作内存附近是否有内存被改写,同时该方法也可以用于统计栈最大使用情况。
-fstack-protector
会在函数返回地址之前插入一个保护字(称为“canary”)。如果在函数执行期间发生了缓冲区溢出,可能会覆盖这个保护字。在函数返回之前,编译器会检查这个保护字是否被修改,如果被修改,程序会立即终止,从而防止潜在的攻击。
stack-protector:保护函数中通过alloca()分配缓存以及存在大于8字节的缓存。缺点是保护能力有限。 stack-protector-all:保护所有函数的栈。缺点是增加很多额外栈空间,增加程序体积。 stack-protector-strong:在stack-protector基础上,增加本地数组、指向本地帧栈地址空间保护。 stack-protector-explicit:在stack-protector基础上,增加程序中显式属性"stack_protect"空间。
通过wfi或wfe指令进入low-power-state。在low-power-state下cpu core保持上电状态,但其大部分时钟停止或者进入时钟门限。这意味着core的绝大部分都处于static state,唯一消耗的功率是用于寻找中断唤醒条件的泄漏电流和少量逻辑时钟。进入low-power-state后将暂停当前的工作直到某个中断或event事件发生会退出low-power-state进入正常运行state。
其唤醒wfi或wfe的interrupt或者event请参考《The AArch64 System Level Programmers’ Model 》D1.6 Mechanisms for entering a low-power state
测试发现period_size=512或者256时均不发生丢包,于是做以下实验:
sampling rate | channel | bit depth | period_size | package size | 是否丢包 |
---|---|---|---|---|---|
48k | 2 | 16bit | 1024 | 4096Byte | 丢包 |
48k | 1 | 16bit | 1024 | 2048Byte | 丢包 |
48k | 2 | 16bit | 512 | 2048Byte | 不丢包 |
48k | 4 | 16bit | 512 | 4096Byte | 不丢包 |
通过实验发现,丢包与period_size相关与package size无关。