Linux 进程调度策略与top命令的PR NI值

Linux进程有SCHED_OTHER/SCHED_BATCH/SCHED_IDLE/SHCED_FIFO/SCHED_RR五种调度策略,前面三种是常规调度策略,后面两种是实时调度策略。具体介绍点击这里

之前一直不能理解的是:RR是分时间片来调度的,是分时调度常用策略,这里为啥还属于实时调度策略。

后来了解到:RR是分时调度常用的策略,也就是说SCHED_OTHER的底层实现也可能是RR。SCHED_RR之所以属于实时调度,是其及时性更高,也就是RR的时间片要比分时的时间片小得多。

Linux的线程也是由进程实现的,只不过是一种可以共享资源的进程(说明在此)。 因此Linux上,线程调度策略应该也不外乎这些。Linux平台上,POSIX线程支持:SCHED_OTHER/SCHED_FIFO/SCHED_RR这三种调度策略。

SCHED_RR和SCHED_FIFO调度的进程属于实时进程,SCHED_OTHER调度的进程属于非实时进程。Linux中大部分进程都是分时进程,实时进程是优先于非实时进程调度的。可以使用top查看,如果PR的值为RT,则为实时进程。

PR和NI的含义

PR 进程的优先级。在Linux 2 …

more ...

C++程序常见的性能调优方式

最近做了一段时间的程序性能调优,写个帖子总结一下。

当然,都还是一些比较初级层面优化,主要是针对一些我称之为“弱性能代码”的优化,还达不到架构优化的高度和算法优化的深度。

个人涉及过的一些优化手段主要有下面几个方面(有些优化手段不仅仅适用于C++程序,比如多重过滤、提前计算等):

冗余的变量拷贝

相对C而言,写C++代码经常一不小心就会引入一些临时变量,比如函数实参、函数返回值。在临时变量之外,也会有其他一些情况会带来一些冗余的变量拷贝。

多重过滤

很多服务都会过滤的部分结果的需求,比如游戏交谈中过滤需要过滤掉敏感词。假设现在有两个过滤词典,一个词典A内容较少,另一个词典B内容较多,现在有1000个词需要验证合法性。

词落在词典A中的概率是1%,落在词典B中的概率是10%,而判断词是否落在词典A或B中的操作耗时差不多,记作N。

那么要判断词是否合法,有两种方式:

  1. 先判断词是否在A中,如果在返回非法;如果不在再判断是否在B中,如果在返回非法,否则返回合法。
  2. 和方式一类似,不过是先判断是否在B中。

现在我们来计算两种方式的耗时:

  1. 1000*N+1000*(1-1%)*N
  2. 1000*N+1000 …
more ...

性能测试随想

分类

性能测试: 系统常规状态运行时,关注机器资源耗用、响应时间等指标。(可能需要长时间保持系统这个状态,观察是否会有资源泄漏)

容量测试: 关注系统单位时间内能够处理的最大请求数

过载测试: 关注系统过载时系统能够提供的服务。理想的情况是系统仍然可以提供自身容量的服务。

峰谷测试: 关注系统从高负载恢复、转为几乎空闲、然后再攀升到高负载、再降低的能力。比如可以观察第二个高负载和第一个高负载时期系统性能指标是否有差异、在负载强烈波动的情况下是或否会有资源泄漏等。

类似的场景还有很多,个人觉得具体还要看被测系统在实际的业务中是否会出现这些场景,不一定要覆盖所有的性能测试子分类。上面列出来的都是我接触过的一些测试场景。

性能测试常见的关注指标:

业务指标:吞吐量(Throughput)和响应时间(或者叫延迟Latency)

系统资源:CPU空闲率、内存使用、网络IO、磁盘读写量、句柄数等等

并发数、QPS、吞吐量的关系:

并发数:有多少用户同时访问我们的服务,注意这并不代表这么多用户一直在请求我们的服务,因为:

  1. 一般用户会等待服务的响应之后才会发起下一次请求
  2. 用户多个操作之间存在“思考时间”

QPS:是指服务器实际每秒处理的请求数,和吞吐量稍不同的是,它是一个实际值,可能会随并发数变化而变化 …

more ...

C++编码优化之减少冗余拷贝或赋值

开始尝试写一些技术上的blog之后,发现一些好处,写的时候可以把一些零散的知识点梳理清楚,而且有空还可以回顾。

最近做了一些模块的性能优化工作,虽然基本都是一些编码上的优化和少量的设计优化,但是优化方式还是比较多且杂的,因此想写个编码优化的系列,把之前曾经遇到过的一些情况记录下来。

当然,在说到某个具体的优化手段时也有可能补充一些书本上介绍的优化方法。

=========背景介绍结束,正文开始=========

之所以说减少拷贝或赋值,而不是减少临时变量,因为有几个情况,并不是临时变量引入的。但目前看来,减少临时变量的产生确是减少冗余拷贝构造的一大途径。

因此,减少冗余拷贝构造准备先简单从两个方面来叙述:临时变量&&非临时变量

临时变量

目前遇到的一些产生临时变量的情况:函数实参、函数返回值、隐式类型转换、多余的拷贝

1. 函数实参

这点应该比较容易理解,函数参数,如果是实参传递的话,函数体里的修改并不会影响调用时传入的参数的值。那么函数体里操作的对象肯定是函数调用的过程中产生出来的。

那么这种情况我们该怎么办呢?

如果callee中确实要修改这个对象,但是caller又不想callee的修改影响到原来的值,那么这个临时变量就是必须的了,不需要也没办法避免。

如果callee中根本没有修改这个对象,或者callee中这个参数本身就是const型的,那么将实参传递改为引用传递是个不错的选择(如果是基本类型的函数实参,则没有必要改为引用),可以减少一个临时变量而且不会带来任何损失。

另外,推荐一个静态代码检查工具cppcheck …

more ...