pref原理及效率计算:
top--PR/NI(priority/nice)
priority
是比较好理解的,即进程的 优先级,或者通俗点说就是程序被 CPU 执行的先后顺序,此值越小进程的优先级别越高
nice
表示进程可被执行的优先级的 修正数值。如前面所说,priority
越小越快被执行,那么加入 nice
值后,将会变为 priority = priority + nice
。由此看出 nice
越小优先权更大,即其优先级会变高,则其越快被执行
在 LINUX 系统中,nice
的范围从 -20
到 +19
(不同系统的值范围是不一样的),正值表示低优先级,负值表示高优先级,值为零则表示不会调整该进程的优先级。nice
为 -20
使得一项任务变得非常重要;与之相反,如果任务的 nice
为 +19
,则表示它是一个高尚的、无私的任务,允许所有其他任务比自己享有宝贵的 CPU 时间的更大使用份额,这也就是 nice
的名称的来意。
进程在创建时被赋予不同的 priority
,而如前面所说 nice
是表示进程优先级值可被修正数据值,因此每个进程都在其计划执行时被赋予一个 nice
值,这样系统就可以根据系统的资源以及具体进程的各类资源消耗情况,主动干预进程的优先级值
/proc/stat
cat /proc/stat
cpu活动信息(此部分信息从系统启动开始累计到当前时刻)-
单位为
jiffies
, 是内核中的一个全局变量,用来记录自系统启动以来产生的 节拍数,在 linux 中一个节拍大致可理解为操作系统进程调度的最小时间片,不同 linux 内核可能值有不同,通常在 1ms 到 10ms 之间。 -
eg:
cpu 65376847 362756 2405159 10834971593 3765180 93399 2395097 0 cpu0 7680302 5263 111909 1355640955 47680 0 185343 0 cpu1 6527638 2261 327795 1356540189 249151 1 24242 0 cpu2 6239465 47114 200809 1354709532 2153662 3610 317002 0 cpu3 7009912 36126 257576 1356116663 162851 1068 87068 0 cpu4 6028713 1692 197911 1356919175 300788 6821 216076 0 cpu5 7110575 1479 124474 1356297947 92620 4248 39901 0 cpu6 7206763 241427 247384 1355030525 691206 11642 242214 0 cpu7 17573475 27390 937298 1343716603 67218 66006 1283248 0 intr 2466653411 753885765 3 0 4 4 0 0 0 1 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 148466005 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1553671397 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10630155 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 0 0 0 ctxt 2905526438 btime 1260187150 processes 4266007 procs_running 5 procs_blocked 0
-
CPU CPU0、CPU1、CPU2、CPU3、CPU4、CPU5、CPU6... 参数解释(第一行):
- user (65376847) 从系统启动开始累计到当前时刻,用户态的CPU时间(单位:jiffies) ,不包含 nice值为负进程。1jiffies=0.01秒
- nice (362756) 从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间(单位:jiffies)
- system (2405159) 从系统启动开始累计到当前时刻,核心时间(单位:jiffies)
- idle (10834971593) 从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(单位:jiffies)
- iowait (3765180) 从系统启动开始累计到当前时刻,硬盘IO等待时间(单位:jiffies) ,
- irq (93399) 从系统启动开始累计到当前时刻,硬中断时间(单位:jiffies)
- softirq (2395097) 从系统启动开始累计到当前时刻,软中断时间(单位:jiffies)
- CPU时间=user+system+nice+idle+iowait+irq+softirq
-
intr
这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。 -
ctx
给出了自系统启动以来CPU发生的上下文交换的次数。 -
btime
给出了从系统启动到现在为止的时间,单位为秒。 -
processes (total_forks)
自系统启动以来所创建的任务的个数目。 -
procs_running
当前运行队列的任务的数目。 -
procs_blocked
当前被阻塞的任务的数目。 -
那么CPU利用率可以使用以下两个方法。先取两个采样点,然后计算其差值:
cpu usage=(idle2-idle1)/(cpu2-cpu1)*100 cpu usage=[(user_2 +sys_2+nice_2) - (user_1 + sys_1+nice_1)]/(total_2 - total_1)*100
-
其他fs文件信息.
- /proc/buddyinfo 每个内存区中的每个order有多少块可用,和内存碎片问题有关
- /proc/cmdline 启动时传递给kernel的参数信息
- /proc/cpuinfo cpu的信息
- /proc/crypto 内核使用的所有已安装的加密密码及细节
- /proc/devices 已经加载的设备并分类
- /proc/dma 已注册使用的ISA DMA频道列表
- /proc/execdomains Linux内核当前支持的execution domains
- /proc/fb 帧缓冲设备列表,包括数量和控制它的驱动
- /proc/filesystems 内核当前支持的文件系统类型
- /proc/interrupts x86架构中的每个IRQ中断数
- /proc/iomem 每个物理设备当前在系统内存中的映射
- /proc/ioports 一个设备的输入输出所使用的注册端口范围
- /proc/kcore 代表系统的物理内存,存储为核心文件格式,里边显示的是字节数,等于RAM大小加上4kb
- /proc/kmsg 记录内核生成的信息,可以通过/sbin/klogd或/bin/dmesg来处理
- /proc/loadavg 根据过去一段时间内CPU和IO的状态得出的负载状态,与uptime命令有关
- /proc/locks 内核锁住的文件列表
- /proc/mdstat 多硬盘,RAID配置信息(md=multiple disks)
- /proc/meminfo RAM使用的相关信息
- /proc/misc 其他的主要设备(设备号为10)上注册的驱动
- /proc/modules 所有加载到内核的模块列表
- /proc/mounts 系统中使用的所有挂载
- /proc/mtrr 系统使用的Memory Type Range Registers (MTRRs)
- /proc/partitions 分区中的块分配信息
- /proc/pci 系统中的PCI设备列表
- /proc/slabinfo 系统中所有活动的 slab 缓存信息
- /proc/stat 所有的CPU活动信息
- /proc/sysrq-trigger 使用echo命令来写这个文件的时候,远程root用户可以执行大多数的系统请求关键命令,就好像在本地终端执行一样。要写入这个文件,需要把/proc/sys/kernel/sysrq不能设置为0。这个文件对root也是不可读的
- /proc/uptime 系统已经运行了多久
- /proc/swaps 交换空间的使用情况
- /proc/version Linux内核版本和gcc版本
- /proc/bus 系统总线(Bus)信息,例如pci/usb等
- /proc/driver 驱动信息
- /proc/fs 文件系统信息
- /proc/ide ide设备信息
- /proc/irq 中断请求设备信息
- /proc/net 网卡设备信息
- /proc/scsi scsi设备信息
- /proc/tty tty设备信息
- /proc/net/dev 显示网络适配器及统计信息
- /proc/vmstat 虚拟内存统计信息
- /proc/vmcore 内核panic时的内存映像
- /proc/diskstats 取得磁盘信息
- /proc/schedstat kernel调度器的统计信息
- /proc/zoneinfo 显示内存空间的统计信息,对分析虚拟内存行为很有用
- /proc/{pid} pid为N的进程信息
- /proc/{pid}/cmdline 进程启动命令
- /proc/{pid}/cwd 链接到进程当前工作目录
- /proc/{pid}/environ 进程环境变量列表
- /proc/{pid}/exe 链接到进程的执行命令文件
- /proc/{pid}/fd 包含进程相关的所有的文件描述符
- /proc/{pid}/maps 与进程相关的内存映射信息
- /proc/{pid}/mem 指代进程持有的内存,不可读
- /proc/{pid}/root 链接到进程的根目录
- /proc/{pid}/stat 进程的状态
- /proc/{pid}/statm 进程使用的内存的状态
- /proc/{pid}/status 进程状态信息,比stat/statm更具可读性
- /proc/self 链接到当前正在运行的进程
gbenchmark配置及使用:
gbenchmark--google benchmark
安装方式(注:***RPP使用cmake方式):
- linux:
git clone https://github.com/google/benchmark.git git clone https://github.com/google/googletest.git benchmark/googletest cd benchmark && mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=RELEASE ../benchmark make -j4 sudo make install # 安装位置: #.h install to /usr/local/include #.so .a install to /usr/local/lib
- windows:略
cmake方式:
- 配置:
- sub tree:
├── benchmark ├── common_pref │ ├── CMakeLists.txt │ ├── main.cpp │ ├── pref001_x.cpp │ ├── pref_x └── gbenchmark └── benchmark-1.7.1.zip
- bash:
# case1: git clone https://github.com/google/benchmark.git touch CMakeLists.txt # case2: mkdir gbenchmark # get the release tags https://github.com/google/benchmark/releases/tag/benchmark-x.x.x.zip # code mkdir common_pref cd common_pref #...your code... touch CMakeLists.txt
- CMakeLists.txt for benchmark and test code folder common_pref:
# 指定CMake编译最低要求版本 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) # 寻找线程包环境 FIND_PACKAGE(Threads REQUIRED) # 设置子目录并构建 ADD_SUBDIRECTORY(common_pref) # googlebenchmark编译开关 OPTION(gbenchmark_en "Enable the gbenchmark: on/off" on) IF(gbenchmark_en STREQUAL "on") # lib: benchmark benchmark_main pthread(无编译测试例) MESSAGE(STATUS "Config: gbenchmark = on, use ExternalProject(error not configure).") ELSEIF(gbenchmark_en STREQUAL "other") # lib: benchmark benchmark_main pthread(编译测试例) MESSAGE(STATUS "Config: gbenchmark = other, use FetchContent.") # 使能cmake外部项目 include(FetchContent) # 下载安装benchmark release版本 fetchcontent_declare( googlebenchmark # URL https://github.com/google/benchmark/releases/tag/benchmark-1.7.1.zip URL ${CMAKE_CURRENT_SOURCE_DIR}/gbenchmark/benchmark-1.7.1.zip PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gbenchmark ) fetchcontent_makeavailable(googlebenchmark) # 指定暴露benchmark头文件 include_directories(${benchmark_SOURCE_DIR}/include) ELSE() # lib: benchmark benchmark_main pthread(编译测试例) MESSAGE(STATUS "Config: gbenchmark = off, we will get clone google benchmark to build.") # 设置子目录并构建 ADD_SUBDIRECTORY(benchmark) # 指定暴露benchmark头文件 include_directories(${benchmark_SOURCE_DIR}/include) ENDIF()
- CMakeLists.txt for common_pref test code:
# 指定CMake编译最低要求版本 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) # 查询当前目录下的/ /test_x 包含的所有.cpp文件 FILE(GLOB COMMON_PREF_SRCS "pref001_x.cpp" "main.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/pref_x/*.cpp") # 生成可执行文件 ADD_EXECUTABLE(common_pref ${COMMON_PREF_SRCS}) # 查找当前目录路径下文件及其他路径下的文件,pthread=${CMAKE_THREAD_LIBS_INIT} IF(gbenchmark_en STREQUAL "on") # TARGET_LINK_LIBRARIES(common_pref libbenchmark ${LINK_LIB}) MESSAGE(STATUS "Config: gbenchmark = on, use ExternalProject(error not configure).") ELSE() TARGET_LINK_LIBRARIES(common_pref benchmark benchmark_main pthread ${LINK_LIB}) ENDIF()
- sub tree:
- 编写demo code:
class Factorial_Fixture : public benchmark::Fixture { public: void SetUp(const ::benchmark::State& state) { //printf("SetUp function.\n"); } void TearDown(const ::benchmark::State& state) { //printf("TearDown function.\n"); } }; BENCHMARK_F(Factorial_Fixture, factorial_pref_64)(benchmark::State& st) { uint64_t a; for (auto _ : st) { a = factorial_pref(64); } // printf("Inter function.\n"); } BENCHMARK_DEFINE_F(Factorial_Fixture, factorial_pref_100)(benchmark::State& st) { uint64_t a; double numFoos = 0, numBars = 0, numBazs = 0; for (auto _ : st) { a = factorial_pref(100); numBars++; numFoos++; numBazs++; } //printf("Inter function.\n"); st.counters["Foo"] = numFoos; st.counters["Bar"] = numBars; st.counters["Baz"] = numBazs; st.counters["FooRate"] = benchmark::Counter(numFoos, benchmark::Counter::kIsRate); st.counters["FooInvRate"] = benchmark::Counter(numFoos, benchmark::Counter::kIsRate | benchmark::Counter::kInvert); st.counters["FooAvg"] = benchmark::Counter(numFoos, benchmark::Counter::kAvgThreads); st.counters["FooAvgRate"] = benchmark::Counter(numFoos,benchmark::Counter::kAvgThreadsRate); //st.counters["BytesProcessed"] = benchmark::Counter(st.range(0), benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::OneK::kIs1024); } /* BarTest is NOT registered */ BENCHMARK_REGISTER_F(Factorial_Fixture, factorial_pref_100)->Threads(100)->Iterations(1)->ThreadRange(1, 8)->UseRealTime(); /* BarTest is now registered */
- test result:
- Benchmark 函数及参数内容
- Time 运行时长
- CPU CPU占用时长
- Iterations 迭代次数
- use(基本指令):
cd build # 整个测试集 ./test/common_test/common_test --gtest_filter=CommonTest* # 单个测试例 ./test/common_test/common_test --gtest_filter=CommonTest.Negative # 列出所有测试例 ./pref/common_pref/common_pref --benchmark_list_tests=ture # 执行所有测试例 ./pref/common_pref/common_pref --benchmark_list_tests=false # 执行指定测试项 ./pref/common_pref/common_pref --benchmark_filter=factorial_pref_xx # 设置输出格式 ./pref/common_pref/common_pref --benchmark_format=<console | json | csv> # 输出到指定文件 ./pref/common_pref/common_pref --benchmark_out=<filename> # 显示计数器参数 ./pref/common_pref/common_pref --benchmark_counters_tabular=true
设计框架:
- 输入参数:
# 1. rpp api
# 2. gbenchmark输入参数设定:
->Arg()
->Args()
->Range()
->Ranges()
->DenseRange()
->ArgsProduct()
->Apply()
->Threads()
->Iterations()
->UseRealTime()
- 输出格式/输出到文件:
- 输出内容包括:
- 测试项函数名及输入参数
- Time 运行时长
- CPU CPU占用时长
- Iterations 迭代次数
- console:
- json:
- csv:
- 输出内容包括:
other tools.
- nbench
- stream
- dd, hdparm
- iperf
- stress
- glmark2
- lmbench