Windows性能分析
Windows运行参数分析
这篇文章较为简单,主要是使用 Windows Performance Record 和 Windows Performance Analysis 来分析在运行一段时间内的各个参数的变化,记录详细的信息。
一般大家都是从任务管理器上面来看机器当前的运行状态,但是,如果我想要了解的更详细一些,并且需要一段特定时间的运行参数,任务管理器仿佛就无能为力了,这时候,可以使用 Windows 测试框架里面的两个小工具来记录分析机器的运行状态。

这篇文章较为简单,主要是使用 Windows Performance Record 和 Windows Performance Analysis 来分析在运行一段时间内的各个参数的变化,记录详细的信息。
一般大家都是从任务管理器上面来看机器当前的运行状态,但是,如果我想要了解的更详细一些,并且需要一段特定时间的运行参数,任务管理器仿佛就无能为力了,这时候,可以使用 Windows 测试框架里面的两个小工具来记录分析机器的运行状态。

元字符(metacharacters)是按照一定规则限制表示的字符。
.匹配所有字符
[]匹配方括号内的所有字符,这个字符按照原样,即使是具有特殊意义的字符,如’,$,>,+’等都是保持字符本意\-除外
[^c1c2]c3c4不匹配’c1,c2’,即不带有c1,c2的c3c4字符串
[c1-c2]匹配c1到c2之间的所有字符
\w匹配任意单个数字,字符串或者下划线,等价于[a-zA-Z_1-9],\w*匹配多个连续字符\w{N}匹配N个连续字符
1
2
3OriginStr = 'spain remain contain aint retain ';
AnsStr = regexp(OriginStr,'\w*','match');
PosStr = regexp(OriginStr,'\w*');
1
2
3
4
5
6
7
8
9
10
11PosStr =
1 7 14 22 27 33
>> AnsStr
AnsStr =
1×5 cell 数组
{'spain'} {'remain'} {'contain'} {'aint'} {'retain'}
可以看出,这个得到的是所有的匹配。而且对于语句regexp(OriginStr,MatchStr,'option'),如果不加option的话,就是得到匹配的一个字符的位置,如果加上option为match的话,就是得到匹配的值。
1
2OriginStr = 'spain remain contain aint retain ';
AnsStr = regexp(OriginStr,'\w* ain','match');
1
2
3
4
5
6
7>> AnsStr
AnsStr =
1×1 cell 数组
{'contain ain'}
可以看到,AnsStr输出的contain ain,即匹配ain的前缀都包括的一串字符串。
\W是匹配\w的补集,\W*跟\w*含义一致\W{N}和\w{N}含义一致。\s等价于[ \f\t\r\n\v],匹配空白字符\S等价于[^\f\t\r\n\v]匹配非空白字符 tips:小写字母和大写字母的含义往往是补集的关系\d匹配单个十进制数\d*匹配多个 tips*匹配多个D是\d的补集,即匹配除了数字以外的所有字符,等价于[^\d]\oN 和\o{N}匹配八进制数N\xN匹配\x{N}匹配十六进制数Nexpr,表达式,这个也就是对于一串字符串,即xp=x&p,[xp]=x|p,即不加[]是且关系,加了[]是或关系,表达式是限定符前面构成的所有字符构成的匹配字符串。
char(10)=\n,即回车。
1 | str = ['some',char(10),'text'] |
输出为
1 | str = |
| 转义字符 | 描述 | 示例 |
|---|---|---|
\a |
警告 | char(7) |
\b |
退格 | char(8) |
\f |
换页符 | char(12) |
\n |
换行符 | char(10) |
\r |
回车 | char(13) |
\t |
水平制表符 | char(9) |
\v |
垂直制表符 | char(11) |
\char |
任意特殊字符 | - |
| 限定符 | 含义 |
|---|---|
| expr * | 多次expr:0~∞ |
| expr ? | 一次expr:0~1 |
| expr + | 一次到多次expr:1~∞ |
| expr{m,n} | m到n次expr:m~n |
| expr{m,} | 大于等于m次expr:m~∞ |
| expr{m} | m次expr:=m |
expr*代表匹配0次或者多次,与任意多个字符匹配
1 | >> regexp('12--asdf--45dfg','\w*','match') |
expr?代表至多匹配1次
1 | >> regexp('12--asdf--45dfg','\w?','match') |
expr+匹配一次或者连续多次
1 | >> regexp('12--asdf--45dfg','\w+','match') |
expr{m,n}匹配m~n次,{0,1}='?'
1 | >> regexp('12--asdf--45dfg','\w{1,3}','match') |
expr{m,}匹配≥m次,{0,}='*';{1,}='+'
expr{n}匹配n次,n={n,n}
表达式+限定词=模式
| 表达式+限定词 | 描述 | 示例 |
|---|---|---|
| expr q | 积极表达式:与尽可能多的expr匹配 | 给定文本 <tr><td><p>text</p></td>,表达式 </?t.*>与介于 <tr 和 /td> 之间的所有字符匹配: |
<tr><td><p>text</p></td> |
||
| expr q? | 消极表达式:与所需尽可能少的expr匹配 | 给定文本<tr><td><p>text</p></td>,表达式 </?t.*?> 在第一次出现右尖括号 (>) 时结束每个匹配项: |
<tr> <td> </td> |
||
| expr q+ | 主动表达式:最大程度的匹配 | 给定文本 <tr><td><p>text</p></td>,表达式 </?t.*+> 不返回任何匹配项,这是因为右尖括号是使用 .* 捕获的且不进行重新扫描。空 {} |
积极表达式:碰到符合条件的,就从开始处匹配到结尾,格式为expr q,q为任意限定符。
1 | >> regexp('<txr><txd><p>text</p></tpd>', '</?t.*>' ,'match') |
消极模式:只要匹配就立即停止搜索,进行下一次匹配,格式为expr q?如
1 | >> regexp('<txr><txd><p>text</p></tpd>', '</?t.*?>' ,'match') |
主动模式:最大程度的匹配,格式为expr q+,如
1 | >> regexp('<txr><txd><p>text</p></tpd>', '</?t.*+>' ,'match') |
主动模式较难理解,我觉得可以这样看,他就就是直接把检测到开头的<字符就开始匹配,知道匹配到无可匹配也就是>为止,这时候才到达匹配模式里面的?部分,所以如果?后面有任何的字符,这个匹配出来的都是空字符串。
这个匹配模式跟匹配出来的结果就是两个,一个是最后一位是?,这时候等价于expr *,最后一位不是?,这时候结果是空字符串。
| 操作符 | 描述 |
|---|---|
| \ | 转义符 |
| (), (?:), (?=), [] | 圆括号和方括号 |
| *, +, ?, {n}, {n,}, {n,m} | 限定符 |
| ^, $, | 位置和顺序 |
| | | “或”操作 |
对于输入的一组数,个数为 n ,求这 n 个数中大小相邻的两个数之间最大差。假设对于任何实数的下取整函数耗时都是 O(1) ,设计此问题的最大间隙解法。例如。
input.txt output.txt
5 0.8
1.1 1.3 2.5 0.7 2.1
其中这个几个数依次排列 0.7<1.1<1.3<2.1<2.5
可以看到,这几个相邻数字之间的差距最大在 2.1-1.3=0.8,所以求得这几个数字之间的最大间距是 0.8
对于这个题目,首先我想到的也就是上面这个思路,首先要判断整个数组的两数相邻与否,那么我要做的就是将其排序,排序完,我再将其相邻数做差,那么也就是的都一个相邻两数的数组,得到数组之后,我就寻找数组中的最大元素,找到最大元素,再对应其索引,我就能找到那两个数字了。
但是,我立刻又想到了复杂度问题,因为排序算法的复杂度最低的是分治法,普通的搜索算法复杂度会比排序低的
复杂度计算如下 $$ O(n\log n)+O(n)+O(n)=O(n\log n) \\ O(n\log n) > O(n) $$ 这个复杂度有点尴尬,因为他不是线性复杂度,不符合题目的要求,所以这个思路是不可行的。
那么我只能换其他的办法来做。

分析一下复杂度,对于找最大最小值,也只需要遍历一次即可,所以复杂度为O(n),等分点只需要得到单位长度即可,单位长度为 $$ l=\frac{max-mix}{n-1} $$ 每个数要判断在哪个段里面也只需要知道自己跟起始处距离几个单位长度即可 $$ seg[i]=\frac{x[i]-minx}{l}+1 $$ 数组seg[i]是一个纽带氏作用,它的索引与x[i]的数的索引是一样的,数组里面存储的数对于的第几个段。这个过程也是用这个公式就可以计算完成的,所以这个过程的复杂度也是O(n),最后需要做差,使用low[i+1] − high[i]得到数组的间隙的最大值即可,最后这个过程的复杂吨也只需要O(n)。
根据前面的分析,每个过程的复杂度均为O(n),那么有限个O(n)的累加复杂度还是O(n),说明这个方法是可行的,满足题目要求。
通过前面的分析,确定了方法二是可行的,那么就可以采用这个方法来进行伪代码书写。
1 | //首先要求出最大值最小值。在这里求出它的索引,这样通过 x 数组访问就可得到它的值了 |
在谈立体角之前,我们先来复习一下球坐标及其面积分。

如上图所示,就是一个典型的球坐标系统,在坐标系中的每一点都可以使用(ρ,ϕ,θ)来描述,与笛卡尔坐标系之间的转化如下
$$ x=\rho\sin\phi\cos\theta\\ y=\rho\sin\phi\sin\theta\\ z=\cos\phi $$
上式就是球坐标和笛卡尔坐标之间的转化,这个转化很容从图上看出来。

从上图可以看出,面积的微元,长为ρdϕ,因为这个方向上的长度为ρϕ,所以微元为ρdϕ;宽为ρsin ϕdθ,这是因为首先要投影到xy平面,在这个平面上的长度为ρsin ϕ,从图上可以看出,这个长度也就是宽,所以微元的宽为ρsin ϕdϕ。所以球面积分的微元面积ρ2sin ϕdϕdθ。
球的表面积计算

表面积的求法,就是对于微元而言,ϕ的取值为0到2π,θ的取值也是0到2π。ρ就是球的半径。 所以微元dS = ρ2sin ϕdϕdθ。表面积的求法如下: S = ∫02πdθ∫02πρ2sin ϕdϕ → 2πρ2(−cosθ)|02π = 4πρ2,这就是很熟悉的圆表面积计算公式了。S圆 = 4πr2,这个公式应该在高中时候就经常使用了。
球帽表面积的计算 
S = ∫02πdϕ∫0θr2sin θdθ $\rightarrow 2\pi r^2(-\cos\theta)|^{\theta}_0=2\pi r^2(1-\cos\theta)=2\pi r^2(1-\frac{r-h}{r})=2\pi rh$,如果h = r,那么求的是半球的面积, 面积S = 2πr2,跟之前的球表面积也对上了。
球面坐标复习到这儿,下面就进入正题了。 ## 立体角
在介绍立体角之前,也先做个铺垫,讲一下角度。

如上图所示,平面角,简称角度定义为圆的弧长与半径之间的比值,单位为弧度(rad)。 $$ \theta=\frac{l}{r} $$
参考平面角的定义,立体角的定义为表面积与半径平方的比值,即
$$ \Omega=\frac{S}{r^2} $$
反映的是从该点出发,向球面区域张成的视野大小,是平面角的三维扩展。

接上面计算的表面积的例子。
需要注意的是,立体角计算也可以理解为是所形成表面在以原点为圆心的球的球面上的投影除以半径的平方。因为要计算的立体角表面不一定是球面的一部分,所以需要先投影到球面再进行计算。
本文主要探讨了几种计算天顶角的算法,并且根据已经测得的标准数据进行了误差对比,以此来判断几种算法的精度。
算法的详情我不是很了解,但是我得到了计算后的数据,将其与标准数据做对比。
MATLAB代码,new1是通过.csv文件导入得到的.mat数据。
1 | %连接日期与时间 |
得到的结果如图:

根据上图可以看出来,在所给的测试数据中,天顶角的计算误差在-0.006~0.01。

Δτ的计算是根据上图用插值法计算的一个线性表达式
$$ \Delta\tau=96.4+0.00158t\\ $$
t = Δday = (yearnow−2060) × 365.2425 参数解释:

根据实际情况,确定了一些参数
| 参数名称 | 参数符号 | 单位 | 参数值 |
|---|---|---|---|
| 经度 | θ | rad | 1.647765346807846 |
| 纬度 | φ | rad | 0.699702497124527 |
| 压强 | P | atm | 0.85862324 |
| 温度 | T | ℃ | 25 |
在计算过程中,如果月份m<2,那么把月份加12,年份减1,这里的INT是表示向0取整。前处理过程如下:
ω = 0.017202786day−1






计算时只需要知道经纬度,赤经赤纬,时角就可以了。

1 | % 主函数 |
1 | % reportFun1函数 |
1 | % ReadFile函数 |
1 | % Preprocess函数 |
1 | % finalStep函数 |

根据文献的第一种算法计算的误差不容乐观,在-0.20.3之间,参考黄冬师兄算的误差,这个扩大了30倍。说明这个算法的精度不是很高,在文献中,这个算法最后也使用了计算数据进行了比较,他给出天顶角的误差范围在-0.190.19,实际计算的比这个范围稍大些,只能说是我们这个数据不够精确或者文献的数据凑得比较好。

1 | % 主函数 |
1 | % reportFun2函数 |
其实最大的不同只是reportFun()函数是不一样的,因为这个是算法的核心,主函数也是类似的,写入数据,调用函数,得到输出,最后画一下误差图。
其他的前处理函数,后处理函数都是一模一样的。

根据文献的第二种算法计算的误差也是不太OK,而且有个严重的问题。从图上看出来,这个集散的误差范围在-0.20.2之间,参考黄冬师兄算的误差,这个误差其实相对于第一种算法减小的不是很多。而且对比文献,他给出天顶角的误差范围在-0.0340.034,实际计算的比这个范围大了6倍,这个误差还是很大的。

1 | % 主函数 |
1 | function [GammaAngle,zAngle] = reportFun3(data) |

从图上看出来,这个计算的误差范围在-0.170.17之间。对比文献,他给出天顶角的误差范围在-0.00930.0093,实际计算的比这个范围大了18倍,说明这个差距还是很大的,是有一定问题的。
.png)
.png)
1 | % 主函数 |
1 | function [GammaAngle,zAngle] = reportFun4(data) |

算法计算的误差在-0.170.17之间。与算法三计算的差不多,文献中写的误差范围是-0.00910.0091,差了17.5倍左右。
使用算法5计算的时候需要给表格中的参数。


.png)
1 | % 主函数 |
1 | % reportFun5函数 |

图上看误差大概也是-0.170.16,文献的误差范围给的是-0.00250.0027,差距是64倍左右,这个差距是很大的。


看了上面两张图,第一张其实看不出来什么,因为误差相对于测量角度的实际值差了100倍左右,能看出来的只是说一天中太阳天顶角是这么分布的。
第二张图和第一张图结合看其实是能看出来一点东西的,看到其实到了6点左右也是天顶角最小,这也是说明这时候高度角最大,太阳在比较高的地方,这时候计算的误差是小的,在00:00和12:00处误差也较大。

看了上面的三幅图,看到这些计算的结果,可以发现误差的分布也有点稀奇古怪,看不出来是什么类型的分布,因为我觉得数据的总数也不是很大,来计算的点数也不够多。可能这样子反应的规律也不是跟明确。总体上来看,还是误差小的占的比例大,所以可能这也是可以稍微有点欣慰的一件事吧。


| 算法 | 文献给的误差范围 | 计算的误差范围 | 相差倍数 |
|---|---|---|---|
| 1 | [-0.19,0.19] | [-0.2,0.3] | 1.05~1.5 |
| 2 | [-0,034,0.034] | [-0.2,0.2] | 5.8 |
| 3 | [-0.0093,0.0092] | [-0.17,0.17] | 18.3 |
| 4 | [-0.0091,0.0093] | [-0.17,0.17] | 18.7 |
| 5 | [-0.0025,0.0027] | [-0.16,0.16] | 59.3 |
从这个表格中看出,几种计算出来的结果都在只能最高保证在0.16。
[1] Roberto Grena Five new algorithms for the computation of sun position from 2010 to 2110 Solar Energy
https://www.sciencedirect.com/science/article/pii/S0038092X12000400
整理的文献为 Revised optical air mass tables and approximation formula 。
文章一开始介绍了一个由 Karsten 在1965年发表的并且广泛被世界所采用的关于大气质量的近似公式,并且讨论了一些由于各个学科对于不同的物理量符号和术语的不同使得读者经常由此而困惑。
其后介绍了一个计算大气光学质量的近似公式,然后说明了在公式中存在的一种不定情况,之后又对这个近似公式用非线性最小二乘法进行修正得到了一组新的系数。后面又根据索引文献[1]文中也多次提到这篇文献,很多都是从这篇文献里面来的。
还有从一篇《基于遥感与地面监测数据的城市气溶胶定量反演研究》,作者是王耀庭,南京师范大学博士论文。
$$ m(\gamma)=\frac{m_{abs}(\gamma)}{m_{abs}(90^{\circ})} $$
$$ m_{abs}(\gamma)=\rho_{0}\int^{\infty}_{0} \frac{\rho}{\rho_{0}}([1-[1+2\delta_{0}(1-\frac{\rho}{\rho_{0}})]]\times [\frac{\cos \gamma}{1+\frac{h}{R}}]^{2})^{-\frac{1}{2}}dh $$ h是相对于海平面的平均高度;
ρ = ρ(h),是在高度h处的大气质量;

根据以上的式子 (1),(2) 和已知的参数表1。要计算这个定积分,那就还需要知道 ρ, 也就是 ρ(h) 在高度 h 处的大气密度,但是我在文献中找不到,这是个问题,不知道是不是需要再去别的地方找这个 ρ,看完了这篇文章之后,知道了这个 ρ 还是没有找到,但是文章已经给出了计算得到的结果的表格。
f(γ) = [sinγ+a(γ+b)−c]−1 γ是高度角,单位是∘;f(γ)是用近似公式计算的m(γ);a, b, c是式子的常数,a = 0.1500,b = 3.885∘,c = 1.253;
a,b,c这三个常数决定于最小二乘法的相对误差,也就是用前面的计算公式计算数据之后,用最小二乘法进行拟合,使用(3)的形式来计算三个常数。
文献后面又介绍了两个不同的参数组合,一个是根据非线性最小二乘法计算的 a = 0.50572, b = 6.07995°, c = 1.6364;一个是根据 Bemporad 的经典大气质量表确定的,a = 0.6556, b = 6.379°, c = 1.757[1],其中文献的表中的 r(γ) 是根据公式(4)计算的相对误差,用来衡量计算大气质量的相对误差。 $$ r(\gamma)=\frac{f(\gamma)-m(\gamma)}{m(\gamma)} $$
对于公式(2),积分会在 γ = 0 和 h 接近于0的地方不定,在这种情况下,这个积分可以通过执行一个特殊的程序来进行计算,在参考文献[1]中有写这个程序。但是在计算的时候有个错误会混入,在地平线上的值 36.2648 会比实际的小 5% 左右。
举例而言,在 Link 和 Neuzil[3] 文章的表中所给出的地平线上的在1962年美国的标准大气的大气质量是38.16,这跟 1959 年 Karsen 用的 ARDC 模型十分接近。Snider 和 Goldman[4] 给出的关于 1962 年的模型的38.10也是高度相似。Treve[5] 使用1959年的 ARDC 模型,得到了在地平线上的相对大气质量分别是 $0.55μm $ 的38.11和在 0.70μm 的38.08。
还有就是采用一种新的标准来却确定式子 (2) 中的参数会优于旧的模型,也就是最新的国际标准化组织的大气模型 (ISO Standrad Atmophere) 代替 ARDC 模型大气(由国际民航组织 ICAO 提出的),这个仅有的变化也就是名义地球半径变为 R = 6.356766 × 106m。
$$ m=\frac{1}{cos \frac{\pi \theta_0}{180^\circ}+0.15\times(93.885-\theta_0)^{-1.253}} $$
其中m是需要计算的大气质量,θ0 是天顶角。
在这篇文章里面,我要做的就是编写一个程序,根据文献中的大气质量近似公式(3),并且用不同的参数组带入,将表格中自变量太阳高度角γ作为自变量带入近似公式计算,再与表格中所给的大气质量数进行作差比较,即验证这个算法是否真的符合实际,如果误差较小,则可以用到我们的项目中去。

上面的这张表格也就说明了在文章计算的数据中天顶角 γ 的取值变化,也就是计算的时候自变量所采用的值。过计算得到了一些结果。

图1 标准大气质量和用其他公式计算的大气质量

图2 四种计算方法与标准大气质量

图3 三种拟合系数计算的大气质量

图4 误差曲线
从上面的图中可以看到,用三种不同的系数计算的相对大气质量以及三组拟合系数的误差曲线,从图中可以看到,三者在天顶角大于 30° 之后都是差不多的经度,主要就是在30°之前的差异。而且可以看到在起始点的时候,第一组和第三组都有很大的误差,特别是第三组,误差都接近于4%,回想文章中提到的积分会在 γ = 0 和 h 接近于 0 的地方不定,需要查阅参考文献[1]来寻找解决方法。但是我看到这个计算的第二组拟合系数表现的很好,不知道是否可以用第二组数据来计算,或者是这三组数据都是在不同的情况下表现的经度水平会不一样。但是有个问题,我们没有找到拟合系数1的这条曲线,在下面会进行说明,实际上它是和其他公式计算的这条曲线重合了。
对比三种方法和一个计算公式,发现计算公式的误差在几个计算方法折中的位置,在角度 >10° 之后,这个计算值的偏差与第二组拟合系数计算的误差一样,都是非常小的。
可以看看在高度角大于10°时候的表现。

图 5 在高度角大于10°时候计算大气质量的误差
这里没有找到拟合系数1这条曲线,是因为他的变化与公式计算的是一模一样的,两条线是重合的。

图 6 拟合系数1和公式计算的天顶角大于10°的误差曲线
这说明,其实拟合系数1也就是将天顶角计算的公式做了稍微的变化,就得到了太阳高度角的,本质上,这两个公式是一模一样的,只是取得系数不同罢了。
在之后使用已经写好的这几种计算方法来计算新的数据值,数据可以在 ‘1.xlsx’ 表格中找到。

图 7 根据所给的数据计算的三天的大气质量数值
可以看到,其实一天内的天顶角并不是全是 0~90° 的,这几天维持在 40° 以下,这时候,查阅标准数据也是差不多在这样的数据范围。
[1] Kasten,“A New Table and Approximation Formula for the Relative Optical Air Mass”,Arch.Meteorol.Geophys.Bioklimatol.Ser.B 14,206-223(1965). [2] R.A Miner,K.S.W.Chamption,and H.L.Pond,The ARDC Model Atmosphere,1959,Air Force Surveys in Geophysics 11(AFCRL,1959) [3] F.Link and L.Neuzil,Table of Light Trajectories in the Terrestrial Atmosphere(Hermann,Paris,1969) [4] D.E Snier and A. Goldman,Refractive Effects in Remote Sensing of Atmosphere with Infrared Transmission Spectroscopy,(Ballistic Research Labratories,June 1975) [5] Y. M. Treve, New Values of the Optical Air Mass and the Refraction and Comparison with Previous Tables,” in Proceed-ings, Second Tropospheric Refraction Effects Technical ReviewMeeting, Technical Documentary Rep. ESD-TDR 64-103, May1964 (National Technical Information Service Order AD-442626), pp.5-391. [6] International Organization for Standardization,Standard Atmosphere,International Standard ISO253(1972) [7] S.L.Valley,Handbook of Geophysics and Space Physics (AFCRL,1965), pp.23. [8] W.H.Jefferys,M.J.Fitzpatrick,B.E.McArthur,andJ.E. McCartney, GaussFit:A System for Least Squares and RobustEstimation (U. Texas at Austin, 1989). [9] A.T.Young,Observational Technique and Data Reduction,” inle to Methods of Experimental Physics(Vol. 12, Astrophysics; Partrmly A:Optical and Infrared),N,Carleton,Ed.(Academic, New York, 1974),p.150.
1 | % 主函数 |
1 | % 计算方法1 |
1 | % 计算方法2 |
1 | % 计算方法3 |
考拉兹函数定义如下
$$ f(x)=\left\{ \begin{array}{**lr**} 3n+1&x为奇数且x\neq1\\ n/2&x为偶数\\ 1&x=1 \end{array} \right. $$ 通过对 x 取不同的值,发现最后都会收敛到 1。求该函数构成算法的上下界。
当然,下界是很容易求出来的,如果输入 n ,下降最快的也就是每次下降 $\frac{1}{2}$,这个下降速度对于的计算时间是 log n 。对于上界,用 MATLAB 带入一些数值计算。得到的结果如下:




















卫星获取地物图像时候,由于存在各种各样的干扰,造成观测值与实际值的偏差,定标就是来(尽可能)消除这些偏差,使得卫星得到的图像与真实的物体之间(尽可能)没有这些偏差,即反映客观事物。
因为卫星所在环境为外太空,会受到强烈的电磁干扰和强辐射,所以器件的老化程度是很快的,这也就是卫星存在使用寿命的一个原因,受限于载荷的使用寿命。那么要延长载荷的工作年限,就需要实时测出其老化程度,对于传感器的灵敏度做出评估,改变具体参数使得其能够继续工作。比如之前对于输入为 10 就能输出 10 ,现在只能输出 5,就乘以系数 2 就可以完成跟之前一样的功能。这样器件就还可以接着使用。
先来看两段代码,这两段代码很简单。main是主函数,调用sum进行求和,其中sum函数参数是指针类型的,也就是说在sum函数进行改变会引起原来的值的改变。
1 | //main.cpp |
1 | //sum.cpp |
如果需要在Linux上面执行出结果,那么打上下面的代码就可以了: 1
2g++ main.c sum.cpp -o a.out
./a.out1
2k+j=7
k=2 j=5
可以看到运行正确了,这个结果也是预料之中的,k 变成了 2,j 变成了 5,这个是在sum里面被改变了值,也会影响到原址的值。
程序到可执行文件需要经过几个阶段:
预编译阶段是把原始的代码文件的需要预编译头加进来,即对于#include的文件进行原样复制,#include文件可以由命令locate得到 1
2
3
4
5
6
7
8
9
10
11ubuntu@ubuntu:~/VSCode/CSAPP深入理解计算机系统$ locate iostream
/usr/include/c++/7/iostream
/usr/lib/x86_64-linux-gnu/libboost_iostreams.so.1.65.1
/usr/share/doc/libboost-iostreams1.65.1
/usr/share/doc/libboost-iostreams1.65.1/changelog.Debian.gz
/usr/share/doc/libboost-iostreams1.65.1/copyright
/usr/share/lintian/overrides/libboost-iostreams1.65.1
/var/lib/dpkg/info/libboost-iostreams1.65.1:amd64.list
/var/lib/dpkg/info/libboost-iostreams1.65.1:amd64.md5sums
/var/lib/dpkg/info/libboost-iostreams1.65.1:amd64.shlibs
/var/lib/dpkg/info/libboost-iostreams1.65.1:amd64.triggersman 1
man stdio
1
2
3
4
5
6
7
8
9
10
11
12
13STDIO(3) Linux Programmer's Manual STDIO(3)
NAME
stdio - standard input/output library functions
SYNOPSIS
#include <stdio.h>
FILE *stdin;
FILE *stdout;
FILE *stderr;
DESCRIPTION1
2g++ -E main.cpp -o main.i
cat main.imain.cpp→main.i。 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42//部分代码,在Linux试一下就知道
namespace std __attribute__ ((__visibility__ ("default")))
{
# 60 "/usr/include/c++/7/iostream" 3
extern istream cin;
extern ostream cout;
extern ostream cerr;
extern ostream clog;
extern wistream wcin;
extern wostream wcout;
extern wostream wcerr;
extern wostream wclog;
static ios_base::Init __ioinit;
}
# 2 "main.cpp" 2
# 3 "main.cpp"
using namespace std;
int sum(int* a,int* b);
int main(int argc, const char** argv) {
int k=-2;
int j=-5;
int* a;
int* b;
a = &k;
b = &j;
cout<<"k+j="<<sum(a,b)<<endl;
cout<<"k="<<k<<"\t"<<"j="<<j<<endl;
return 0;
}#include里面的东西原样复制到main.cpp代码文件里面,整合到一起,就叫做预编译过程。 ### C++编译阶段 C++编译阶段就是把预编译好的文件编译成汇编代码,个人觉得这个过程跟翻译差不多,把一种语言翻译成另一种语言,命令如下。 1
2g++ -S main.i
cat main.sg++命令默认会有-o main.s添加上,即会产生main.s文件产生。 产生的main.s文件如下,由于太长,截取了部分。
1 | .file "main.cpp" |
从上面的代码看出,这是个汇编代码,也就完成了main.i→main.s的转化。
rof是relocatable object file的简称,称为可重定向目标文件。
1 | g++ -c main.s |
输出的文件为main.o,这个文件不是文本文件,是一个二进制文件。
文本文件:由ASCII码组成的文件,可以由文本编辑器直接打开 二进制文件:除了文本文件之外的所有文件,如图片格式文件就属于二进制文件,这种文件需要专门的解码软件打开,如果使用文本编辑器打开就是乱码的。
eof是executable object file的简称,称为可执行目标文件。
按照前面的步骤(预编译→C++编译 → rof文件生成)得到sum.o文件。然后进行:
1 | g++ main.o sum.o |
这时候会产生一个新的文件为a.out,这个名字可以自己取,也就是把默认的那个语句加上,如: 1
g++ main.o sum.o -o main.out
.x也可,只不过.out是在Unix操作系统上第一个实现的可执行文件的后缀名,就保留了下来。
之后就运行: 1
./a.out
1
2k+j=7
k=2 j=5a.out的代码和数据复制到内存,然后将控制转移到这个程序的开头。

以下答案均不代表正确答案,仅代表作者观点
用户级线程不能被时钟剥夺,除非整个进程的时间片用完。内核级线程可以单独地被剥夺。在后一种情况下,如果线程运行过久,时钟将中断该当前进程,因而当前线程也被中断。内核可以自由地从同一个进程中选取其他线程运行。