两个数A B,A<B,两种操作:A=A+1 或 A=A*2,求A到B的最少操作次数。
首先如果A、B的二进制前缀不一样则一直A=A+1
然后A=A<<1,A、B前缀不一样再A=A+1
两个数A B,A<B,两种操作:A=A+1 或 A=A*2,求A到B的最少操作次数。
首先如果A、B的二进制前缀不一样则一直A=A+1
然后A=A<<1,A、B前缀不一样再A=A+1
blog.csdn.net/zhangskd/article/details/7609465
问题1:当发送方长时间受到应用程序的限制,不能发送数据时,会使拥塞窗口无效。TCP是根据拥塞窗口来动态地估计网络带宽的。发送方受到应用程序的限制后,没有数据可以发送。那么此时的拥塞窗口就不能准确的反应网络状况,因为这个拥塞窗口是很早之前的。
问题2:当发送方受到应用程序限制,不能利用完拥塞窗口,会使拥塞窗口的增长无效。TCP不断调整cwnd来测试网络带宽。如果不能完全使用掉cwnd,就不知道网络能否承受得了cwnd的数据量,这种情况下的cwnd增长是无效的。
TCP sender受到的两种限制
(1) application-limited :when the sender sends less than is allowed by the congestion or receiver window.
(2) network-limited:when the sender is limited by the TCP window. More precisely, we define a network-limited period as any period when the sender is sending a full window of data.
TCP’s congestion window controls the number of packets a TCP flow may have in the network at any time. However, long periods when the sender is idle or application-limited can lead to the invalidation of the congestion window, in that the congestion window no longer reflects current information about the state of the network.
The congestion window is set using an Additive-Increase, Multiplicative-Decrease(AIMD) mechanism that probes for available bandwidth, dynamically adapting to changing network conditions. This AIMD works well when the sender continually has data to send, as is typically the case for TCP used for bulk-data transfer. In contrast, for TCP used with telnet applications, the data sender often has little or no data to send, and the sending rate is often determined by the rate at which data is generated by the user.
An invalid congestion window also results when the congestion window is increased (i.e., in TCP’s slow-start or congestion avoidance phases) during application-limited periods, when the previous value of the congestion window might never have been fully utilized. As far as we know, all current TCP implementations increase the congestion window when an acknowledgement arrives, if allowed by the receiver’s advertised window and the slow-start or congestion avoidance window increase algorithm, without checking to see if the previous value of the congestion window has in fact been used.
This document proposes that the window increase algorithm not be invoked during application- limited periods. This restriction prevents the congestion window from growing arbitrarily large, in the absence of evidence that the congestion window can be supported by the network.
发送方在发送数据包时,如果发送的数据包有负载,则会检测拥塞窗口是否超时。如果超时,则会使拥塞窗口失效并重新计算拥塞窗口。然后根据最近接收段的时间,确定是否进入pingpong模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
tcp_event_data_sent()中,符合三个条件才重置cwnd:
(1)tcp_slow_start_after_idle选项设置,这个内核默认置为1 (2)tp->packets_out == 0,表示网络中没有未确认数据包 (3)now - tp->lsndtime > icsk->icsk_rto,距离上次发送数据包的时间超过了RTO
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 |
|
那么调用tcp_cwnd_restart()后,tp->snd_cwnd是多少呢?这个是不确定的,要看闲置时间delta、闲置前的cwnd、路由器中设置的initcwnd。当然,最大概率的是:拥塞窗口降为闲置前cwnd的一半。
在发送方成功发送一个数据包后,会检查从发送队列发出而未确认的数据包是否用完拥塞窗口。 如果拥塞窗口被用完了,说明发送方收到网络限制; 如果拥塞窗口没被用完,且距离上次检查时间超过了RTO,说明发送方收到应用程序限制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
在发送方收到应用程序的限制期间,每隔RTO时间,都会调用tcp_cwnd_application_limited()来重新设置sshresh和cwnd,具体如下:
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 |
|
发送方受到应用程序限制,且限制的时间每经过RTO后,就会调用以上函数来处理snd_ssthresh和snd_cwnd:
(1)snd_ssthresh = max(snd_ssthresh, ¾ cwnd)
慢启动阈值并没有减小,相反,如果此时cwnd较大,ssthresh会相应的增大。ssthresh是一个很重要的参数,它保留了旧的信息。这样一来,如果应用程序产生了大量的数据,发送方不再受到限制后,经过慢启动阶段,拥塞窗口就能快速恢复到接近以前的值了。
(2)snd_cwnd = (snd_cwnd + snd_cwnd_used) / 2
因为snd_cwnd_used < snd_cwnd,所以snd_cwnd是减小了的。减小snd_cwnd是为了不让它盲目的增长。因为发送方没有利用完拥塞窗口,并不能检测到网络是否能承受该拥塞窗口,这时的增长是无根据的。
在发送完数据包后,通过对拥塞窗口有效性的检验,能够避免使用不合理的拥塞窗口。
拥塞窗口代表着网络的状况,通过避免使用不合理的拥塞窗口,就能得到正确的网络状况,而不会采取一些不恰当的措施。
在上文的两种情况下,通过TCP的拥塞窗口有效性验证机制(TCP congestion window validationmechanism),能够更合理的利用网络、避免丢包,从而提高传输效率。
RFC2861
http://tieba.baidu.com/p/2687199243?see_lz=1
热插拔驱动(Hotplug Driver)是控制cpu负载控制核心上线下线的驱动
注意:所有热插拔驱动都是根据负载调节cpu上下线,只是策略有不同。这不是“高通异步专利”
1
|
|
这个热插拔驱动其实工作的蛮不错的。各个厂商之间略会有不同。个人建议使用8064以后机器的不使用第三方的热插拔驱动
三星的热插拔驱动是集成在了governor(调速器)中的,这个调速器可以看作ondemand+hotplug,工作方式为多核低频
两个字:渣渣
建议使用开发者开发的热插拔驱动
方法1: 使用kernel tuner
方法2: 使用脚本(只针对高通机器):
1 2 3 4 5 6 7 8 9 |
|
注意: 这样做将没有热插拔驱动工作,在空载时依然会有两个核心上线
步骤1: 将governor设置为performance
方法很简单,用fauxclock,trickester mod,kernel tuner都可以搞定,并且不占用资源采样负载
弊端:如果不修改温度配置文件,将会受到降频影响
步骤2: 修改权限让温控进程无法对其降频
1 2 3 4 5 6 7 8 9 |
|
注意:cpu频率以khz为单位,比如1728mhz应该在这里写为1728000
步骤1: 将governor设置为performance
方法很简单,用fauxclock,trickester mod,kernel tuner都可以搞定,并且不占用资源采样负载
弊端:如果不修改温度配置文件,将会受到降频影响
1 2 3 4 |
|
步骤2:
1 2 |
|
注意:gpu频率以hz为单位,比如400mhz应该在这里写为400000000
锁定频率对游戏性能很重要。根据我目前的结果来看,1.7g的krait 300似乎已经有点拖不动adreno 320了,而且随着频率降低,帧数跟着降低。但是对于日常使用来说,高频率只是一瞬间的事,并不需要多久,长期高频率对电池和发热的影响都会非常大。不推荐锁频,除非你要作性能测试
(1) 什么是governor
governor大多数中文翻译为调速器,也叫调速策略。故名思议,根据cpu负载不同而如何决定提升或者降低频率靠的就是governor
(2) 为什么governor很重要
随着linux内核的更新,governor也会带来许多新功能来提升用户体验、响应速度、省电等。另外不同厂商对于不同governor的优化也是不同的。比如高通,对ondemand/msm-dcvs的优化非常好,然而对于小米用的interactive确实基本没怎么优化,在高通内核中的interactive非常之老旧,对于性能和省电都不利。在游戏中,htc的ondemand表现非常捉急,在需要提升频率的时候还按着不动,从而导致掉帧、顿卡等。切换到performance或者msm-dcvs会好不少。代表:riptide gp, asphalt 8,real racing 3
(3) 安卓上常见governor种类
ondemand 故名思议,按需。ondemand根据cpu的负载来决定提升和降低频率,工作方式比较简单,也是最常见的一个governor
interactive 故名思议,交互。这个governor重点就是注重交互时的体验,它会比ondemand更快地提升到最高频率,而在降频时确实按照设定的时间慢慢地降。这么做会让系统很流畅,电量嘛,你懂的。
conservative 这个governor被开发者戏称为slow ondemand,它为了节电会限制cpu频率的提升,结果就是卡
performance 一直最高频
powersave 一直最低频
userspace 这个governor实质上就是让软件设定频率。比如在运行stability scaling test的时候,软件就会将其设为userspace
intellidemand intellidemand是faux123基于ondemand开发的一个governor,它和ondemand的主要区别就是在浏览网页的时候会限制频率,然后配合faux的热插拔驱动intelli-plug会获得比较好的省电效果
pegasusq 三星基于ondemand开发的热插拔governor
msm-dcvs msm(高通处理器前缀)-dcvs(dynamic clock & voltage scaling 动态频率电压调整) 这个governor是高通给krait架构开发的,具体有什么魔力我也不清楚,只是用它玩游戏的时候感觉比ondemand流畅多了
ondemand 这个和cpu的是一样的,按需调整,根据负载决定频率
performance 永远最大频率
simple 这个governor是faux123对adreno 3xx开发的一个governor,其中参数有laziness和thresholds。前者数值分布1-10,决定的是忽略多少降频请求,数字越大性能和耗电都越高;后者是提升频率的阀值,即gpu达到多少负载提升频率,数值分布0-100,数字越大性能和耗电都越低
(3) 如何切换
最简单的当然是在fauxclock,trickester mod等软件里面切换
cpu:
1 2 3 4 |
|
gpu:
1
|
|
中文名:输入输出 调度器/io 调度器
(1) 为什么io scheduler很重要
io scheduler完全决定了磁盘的读写性能,而这对于用户体验的影响是极大打
(2) 安卓上常见io scheduler
completely-fair-quening
完全公平队列,是anticipatory模式的替代品,没有过多的做预测性调度,而是根据给定的进程io优先级,直接来分配操作的顺序。这个模式在linux上表现良好,但也许并不是最适合android的io调度模式,太强调均衡,而降低了连续读写数据的性能。
高通默认的就是这个,强烈建议改掉,根本不适合移动设备
这个调度模式会把所有的数据请求直接合并到一个简单的队列里。不适合有机械结构的存储器,因为没有优化顺序,会增加额外的寻道时间。属于最简单的一个调度模式,无视io操作优先级和复杂性,执行完一个再执行一个,如果读写操作繁多的话,就会造成效率降低。
nvidia默认,有时候会造成顿卡,但是听说这个scheduler对省电比较有帮助
顾名思义,用过期时间来排序io操作顺序,保证先出现的io请求有最短的延迟时间,相对于写操作,给读操作更优先的级别。是比较好的一个调度模式。
性能不错
read over write
顾名思义,这个scheduler会优先处理读的请求。在移动设备上读的请求远远多于并且重要于写的请求,并且随机读取速度很重要。这个governor允许单或者双线程的读写,在同时有读写的情况下优先保证读,比较适合移动设备。
fair-iops 这个调度器虽然和cfq一样追求平均的优先级,但是是根据闪存设备重新设计的一个governor,各方面表现良好,是我列出来的五个scheduler里面性能最好的一个
如果有,强烈推荐fiops
simple-io 在安卓上其实调度器越简单效果越好。sio就是最简单的一个调度器。不过还是有缺点的,就是随即读写性能不太好。在fiops出来以后,这个scheduler基本就被冷落了
这个其实奇怪。按理说缓存应该是越大越好,但是在安卓上好像不是这样,是越大越省电,越小系统越流畅,具体原理我也不懂。只列下方法
依旧,fauxclock,trickester mod等可以修改
命令:
emmc内置闪存:
1
|
|
sd卡:
1
|
|
默认为128k,如果想省电可以设成2048k
entropy是一个叫混乱度的东西,好像是物理化学里面的,根据faux123的解释,闪存设备根本不需要entropy,所以就把它关掉来提高性能
fauxclock里面可以关闭
命令
1 2 |
|
高通从krait 200上引进,但是有bug,在krait 300上得到了修复
总共4个状态:
c0, wfi
c1, rentention
c2, standalone_power_collapse
c3, power_collapse
数字从低到高代表了睡眠程度的高低,数字越高的状态越省电
intel也有这个,haswell就是凭借着强大的c-states调整在tdp更高的情况下获得了更低的耗电和更长的续航。桌面上比如e3可以将c6状态打开,能在0.8v左右稳定在3.3g
高通的c-states和intel不一样,在平时工作的时候高通处理器进入c states的时间很少,主要集中在关屏深睡眠的时候
fauxclock可以打开,krait 300建议打开c0 c2 c3
命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
从Android 4.0以后大家可以从build.prop里面发现这么几行:
1 2 |
|
在4.2以后还可以看到这一行
1
|
|
这就是构图方式
从谷歌4.2的build.prop的变化来看,谷歌已经开始强制使用mdp。性能更强但是耗电更低,何乐而不为
cpu: 故名思议,cpu构图
gpu: gpu构图,在开发者选项中选择“关闭hw叠加层”和只设置debug.sf.hw=1都是让gpu构图
c2d: c2d构图,这个在2.x时代就已经被抛弃了,比gpu构图还烂
dyn: 这个似乎不错,但是所有高通机器的rom里面只有one的cm在用这个,而且开发者对这个构图方式的看法褒贬不一,就连这个选项是否生效都有争议。
mdp: 从firefox的开发者那里得知,新一点的机器都是有mdp管线的,比gpu构图性能更强、更省电。谷歌也因此强制使用这个构图方式
最常见的影响当然就是fps meter打开变卡了
firefox开发者的解释: https://bugzilla.mozilla.org/show_bug.cgi?id=911391
当叠加层数量低于mdp管线数量的时候,所有的构图都用mdp完成,不仅性能比gpu构图更好,而且还更省电。但是一旦叠加层数量超过mdp管线的数量,系统就会自动使用“部分mdp构图”,实质上就是要mdp和gpu合作构一帧的图。那么这个时候,就会导致性能下降
为什么打开一些overlay软件就变卡了呢?这就说明打开这类软件以后,比如fps meter,整个图层的数量已经超过了mdp的管线数量,系统启用gpu构图,导致系统、游戏流畅度下降。为什么有些人开始还不觉得fps meter对性能有影响呢?原因可能有三个:1. 他们还在4.2以下,还没用过mdp,一直都在用gpu构图;2. 他们一直都关掉了hw叠加层,也是一直用gpu构图,所以无法感知gpu构图对系统流畅度的严重影响;3. 他们打开了一些overlay软件,但是没有超过mdp的管线数量,没有进入gpu构图
构图的影响还不止这些,如果有人有one,可以试试把这一行
1
|
|
从build.prop里面删掉
重启以后,反复按app抽屉的图标,对比与没删之前的流畅度。另外在贴吧等软件中,mdp构图也会增加滑动的流畅度。至于视频:1. 我没有高速摄像机;2. 这是非常容易感知的问题,耍赖不承认我是没办法的
mdp的缺点:
对于一些老的应用,mdp会造成负面影响,对流畅度负加成:比如在使用老版re管理器的时候,转移到多任务界面会有卡顿,而新版则非常流畅。 在叠加层数量超过mdp管线数量的时候,会转为“部分mdp构图”,mdp管线和gpu合作构图
不过谷歌已经强制使用mdp,随着软件更新,更快更省电的mdp构图将会逐渐替代gpu构图
很多厂商被逮着了“作弊”,其实我觉得根据不同的app调整策略不是坏事,但是你不开放给用户那就有问题了。凭什么只能跑分得到这样的待遇?厂商真的应该好好反思
1.作弊文件位置:
三星: TwDVFSApp.apk
HTC: /system/bin/pnpmgr; /system/etc/pnp.xml
NVIDIA:/system/app/NvCPLSvc.apk/res/raw/tegraprof.txt
2.如何对待?
作弊固然可耻,但是干掉这些东西又不是明智的选择。虽然这些文件有对跑分的专门配置和优化,但是它们还对普通应用程序/游戏有着配置。比如pnpmgr,它管理者省电模式、touch_boost、60fps视频cpu提频等等非常有用的调整;比如tegraprof,这里面更是有不少针对游戏优化的配置文件。关掉它们只会给用户体验减分。我希望所有厂商能够开放配置,让用户自由定制,而不是现在的加密处理。
注明机型,驱动版本,系统版本,内核类型(是官方还是第三方,编译器是什么。换一个编译器可以让某些性能差别达到20%)构图方式
不要在开启fps meter的同时打开其他悬窗监控软件。fps meter统计的是整个图层的平均帧数,开启其他悬窗监控软解无论刷新率调到多少都是不准的(除非overlay在fps meter上面)
测试的时候最好关掉温度进程,以防止意外降频
对比测试的时候注意变化量,在变化量超过一个的时候对比测试结果不可信
如果想反映整个游戏的帧数情况,用Adreno Profiler。在没有高速摄像机的情况下,这个比视频靠谱得多。https://developer.qualcomm.com/mobile-development/mobile-technologies/gaming-graphics-optimization-adreno/tools-and-resources
很多人抱怨手机降频,其实这不是坏事,降频厉害,也是oem厂商所为,与soc厂商关系不是太大
可能抱怨最多的就是高通机器了,这里讲下高通机器的温度控制进程的基本调试
关闭:
1
|
|
开启:
1
|
|
关闭温控以后,除非内核中也有温度保护,机器将不会降频,散热设计不好的机器很有可能因此烧毁。请谨慎考虑关闭温控进程
方法1:使用last_kmsg
1
|
|
在adb目录下,找到last_kmsg文件,用记事本(推荐用notepad++/notepad2)打开,搜索sensor
方法2: 使用cat命令逐个查看
1
|
|
显示出的数值即该传感器的温度
毫无疑问,温度最高的那几个就是cpu温度传感器
配置文件的路径在 /system/etc/thermald.conf,权限为644
对于大部分高通机器,打开即可编辑。对于HTC机器,这个文件是加密的,只能自己写。
对于三星的机器,这个文件会是一个软链,比如E330S软链到了thermald-8974.conf文件,那么你真正应该修改的文件则是thermald-8974.conf
获取cpu频率表:
1
|
|
获取gpu频率表:
1
|
|
注意: 部分三星机器,比如E330S无法查看gpu频率
步骤1: 了解thermald.conf的语言
1 2 3 4 5 6 7 8 9 10 11 |
|
步骤2: 定义总采样时间
1
|
|
数值越低采样越勤,也越耗费资源。不建议修改
步骤3: 定义传感器
1 2 3 4 5 6 |
|
步骤3.1:定义所需要的传感器
在你获得的传感器中,选择所需要的传感器。据我所知,绝大多数高通机器打sensor7, sensor8, sensor9都是cpu温度传感器,若要使用其他温度传感器,直接修改这个数字即可
步骤3.2:定义该传感器的采样时间
sampling 1500
数值越低,采样越勤,不建议修改
步骤3.3: 修改触发行为的温度阀值,即高于这个设定的温度就会采用当前定义的行为,比如降频
thresholds 54 57 64 70 75
步骤3.4: 修改回到上一行为的温度阀值,即低于这个设定温度就会回到上一个温度阀值所定义的行为(shutdown命令除外)
thresholds_clr 51 54 57 64 70
步骤3.5: 定义行为,最常见的就是cpu,gpu,shutdown,若要定义多个行为,则用加号相连
actions gpu+cpu gpu+cpu cpu cpu cpu
步骤3.6: 定义所采取的行为的具体数值,即降频降到多少。
action_info 400000000+1728000 320000000+1134000 1026000 918000 702000
注意: 其数值顺序必须与actions的顺序一模一样,最好与cpu和gpu频率表一致,否则容易出错。千万不要像三星官方一样敷衍了事。
个人认为降频并不是一件坏事,在soc发热越来越大的今天,降频是厂商保证用户体验的一种方式之一:降低发热,降低耗电
但是我希望每个厂商都能像小米一样开发不同的模式,在需要降频省电的时候用一套温控配置,在需要性能的时候用另一套温控配置;而大多数国际厂商,比如三星,htc,nvidia,仅仅在跑分的时候使用了更高的温度配置,而且是用户无法选择的。这种行为应该表示抗议!强烈谴责!