首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10000篇文章
优秀的个人博客,低调大师

内核优化之PSI篇:快速发现性能瓶颈,提高资源利用率

欢迎关注【字节跳动 SYS Tech】公众号。字节跳动 SYS Tech 聚焦系统技术领域,与大家分享前沿技术动态、技术创新与实践、行业技术热点分析等内容。 背景介绍 了解操作系统原理的同学应该知道,业务进程的运行性能取决于多种系统资源的分配。比如进程需要等待某些 IO 的返回,需要从伙伴系统分配内存,可能会由于 memory cgroup 的限制或者系统内存的水线配置而进行内存回收,进程运行需要调度器分配 CPU 时间,可能由于 CPU cgroup 的 quota 配置或者系统负载较大而等待调度器的调度。 所以一个进程的运行过程实际上是一个不断等待不断执行的过程,过多的等待会对进程的吞吐和延时造成负面影响,是否有一种内核机制能够量化这些等待时间呢? PSI 通过 hook CPU 调度器和 hook 一些 IO 和 memory 的关键点,来得到一个线程开始等待某种资源和结束等待某种资源的时间点以及程序运行的时间,然后用移动平均算法算出一个表示 pressure stall information 的百分比来量化。 用途 PSI 监控机制给我们提供了一种实时量化指标,反映业务进程的吞吐和延时,是否有某种系统资源上的瓶颈。这可以帮助我们了解特定业务进程的资源需求,协助业务的部署密度。并且可以根据 PSI 指标,动态调节业务的部署和资源的分配,来保证特定业务的性能要求和系统的健康程度。 使用接口 监控接口 PSI 通过 /proc 文件系统导出了三个接口文件,用于反映实时的系统级别的 CPU,memory 和 IO 压力。 # cat /proc/pressure/cpu some avg10=0.00 avg60=0.00 avg300=0.00 total=0 full avg10=0.00 avg60=0.00 avg300=0.00 total=0 # cat /proc/pressure/memory some avg10=0.00 avg60=0.00 avg300=0.00 total=0 full avg10=0.00 avg60=0.00 avg300=0.00 total=0 # cat /proc/pressure/io some avg10=0.00 avg60=0.00 avg300=0.00 total=0 full avg10=0.00 avg60=0.00 avg300=0.00 total=0 其中的 some 表示至少有一个线程有资源瓶颈的时间比例,full 表示所有线程都有资源瓶颈的时间比例。 full 状态相当于整个系统由于资源瓶颈没有执行任何 productive 的代码,白白浪费了 CPU 资源。而 some 则是某些线程有资源瓶颈,另外的线程还是在利用 CPU 资源执行 productive 的代码。 avg10,avg60,avg300 则是在 10s,60s,300s 的时间窗口计算的移动平均百分比,表示资源瓶颈状态的时间比例,可以给我们短期、中期和长期的量化了解。total 则是资源瓶颈状态的绝对时间积累,我们也可以对 total 的变化进行监控来发现延时抖动的情况。 trigger 接口 除了读取这些接口文件获取实时指标外,我们还可以写入这些接口文件向内核注册 trigger,通过select(),poll() 或 epoll() 等待 trigger 事件的发生。 # 150ms threshold for partial memory stall in 1sec time window echo "some 150000 1000000" > /proc/pressure/memory # 50ms threshold for full io stall measured within 1sec time window echo "full 50000 1000000" > /proc/pressure/io trigger 示例代码 #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <poll.h> #include <string.h> #include <unistd.h> /* * Monitor memory partial stall with 1s tracking window size * and 150ms threshold. */ int main() { const char trig[] = "some 150000 1000000"; struct pollfd fds; int n; fds.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK); if (fds.fd < 0) { printf("/proc/pressure/memory open error: %s\n", strerror(errno)); return 1; } fds.events = POLLPRI; if (write(fds.fd, trig, strlen(trig) + 1) < 0) { printf("/proc/pressure/memory write error: %s\n", strerror(errno)); return 1; } printf("waiting for events...\n"); while (1) { n = poll(&fds, 1, -1); if (n < 0) { printf("poll error: %s\n", strerror(errno)); return 1; } if (fds.revents & POLLERR) { printf("got POLLERR, event source is gone\n"); return 0; } if (fds.revents & POLLPRI) { printf("event triggered!\n"); } else { printf("unknown event received: 0x%x\n", fds.revents); return 1; } } return 0; } cgroup接口 使用cgroup-v2 时 PSI 还提供了 per-cgroup 的 pressure stall information 接口,用于监控和跟踪特定 cgroup 的资源瓶颈状态。 cgroupfs 的 mount 点的每个子目录都有三个文件接口:cpu.pressure,memory.pressure,io.pressure。读取文件内容的形式和 /proc/pressure 一样,同样也可以进行写入注册 trigger 事件。 性能优化 PSI 机制为我们提供了一种实时量化系统级别或 cgroup 级别是否存在资源瓶颈的指标,对于调度部署业务负载和资源分配有很好的指导作用,而且可以明确业务进程的吞吐和延时方面存在的资源瓶颈。 但是 PSI 机制不是没有开销的,它 hook 了调度器和 IO,memory 等热点路径,统计等待资源的时间并计算比例,这些都是有开销的。为了在生产环境常态化开启 PSI 特性,我们需要解决 PSI 的性能开销问题。 问题场景 我们在线上场景遇到的一起 PSI 性能问题的 perf top 热点,其中 psi_task_change() 热点比较高,对当时业务进程的吞吐和延时都有较大的负面影响。 代码分析 psi_task_change() 的热点开销问题可能有两个方面的原因:一个是它本身执行比较耗时,另一个是它被调用的频率太高。 psi_task_change()函数的作用通过名字可知,在 PSI 的所有 hook 点都会发生 task 状态的变化,比如开始等待 memory,结束等待 memory,开始等待 CPU,结束等待 CPU 等,因此该函数调用频率较高。 另外psi_task_change()内部实现不仅需要改变该 task 的状态,还要改变 task 所在每个 cgroup 的状态,改变前需要统计上个状态的时间。 详情参见以下代码片段: void psi_task_change(struct task_struct *task, int clear, int set) { int cpu = task_cpu(task); struct psi_group *group; bool wake_clock = true; void *iter = NULL; if (!task->pid) return; psi_flags_change(task, clear, set); /* * Periodic aggregation shuts off if there is a period of no * task changes, so we wake it back up if necessary. However, * don't do this if the task change is the aggregation worker * itself going to sleep, or we'll ping-pong forever. */ if (unlikely((clear & TSK_RUNNING) && (task->flags & PF_WQ_WORKER) && wq_worker_last_func(task) == psi_avgs_work)) wake_clock = false; while ((group = iterate_groups(task, &iter))) psi_group_change(group, cpu, clear, set, wake_clock); } 通过以上代码分析,我们发现有两个可以优化的方向:尽量减少psi_task_change()的调用,以及尽量减少psi_group_change()的调用。 代码优化 1. 利用共同的cgroup 我们需要知道的一个捷径是当task A切换到task B时,如果A和B存在共同的cgroup时,其实cgroup的状态是没有变化的,只是task A和task B的状态变化了。 所以根据这个事实我们可以优化发生频率比较高的task_switch hook,不再遍历改变task A的所有cgroup,然后再次遍历task B的所有cgroup,而是进行整合:只改变task A和task B的不同cgroup分支,直到相同的cgroup停止,减少psi_task_change()的调用开销。 2. 减少sleep导致的状态切换 sleep before: psi_dequeue() while ((group = iterate_groups(prev))) # all ancestors psi_group_change(prev, .clear=TSK_RUNNING|TSK_ONCPU) psi_task_switch() while ((group = iterate_groups(next))) # all ancestors psi_group_change(next, .set=TSK_ONCPU) sleep after: psi_dequeue() nop psi_task_switch() while ((group = iterate_groups(next))) # until (prev & next) psi_group_change(next, .set=TSK_ONCPU) while ((group = iterate_groups(prev))) # all ancestors psi_group_change(prev, .clear=common?TSK_RUNNING:TSK_RUNNING|TSK_ONCPU) 通过以上对比可知:优化掉了 psi_dequeue 触发的 psi_group_change() 调用,将状态的改变整合放到了psi_task_switch(),减少了 cgroup 的状态切换开销。 总结 PSI 的优化成果已经合入上游的主线内核,也合入了 veLinux 开源的 5.4 内核版本,现在部署的 5.4 内核都已经常态化开启了 PSI 机制,配合 cgroup-v2 的使用会更好地帮助我们发现业务性能的资源瓶颈,以及动态的自适应运维和资源分配。 社区也已经存在基于 PSI 机制的 OOMD(out of memory daemon)service,可以更好地应对系统 OOM 的场景,同时在字节内部也积极开发和应用基于 PSI 机制的动态资源管控程序,以在保证业务性能的同时,提高资源利用率。 veLinux 内核 GitHub 地址:https://github.com/bytedance/kernel

优秀的个人博客,低调大师

微软Skype即将迎来重大升级:带来快速、有趣、愉悦和流畅的体验

微软今天发布预告,表示 Skype 目前正在积极开发中,新版本有望在未来几个月内和大家见面。随着最近面向消费者的 Microsoft Teams 的推出,大多数人认为微软将退出 Skype。不过微软今天透露了 Skype 的未来计划,目标是建立一个改进的、更快的、可靠的、看起来超级现代的Skype。 作为Skype 中重要的部分之一,微软称其为“call stage”(通话舞台)。新版在通话期间显示的网格将很快包含通话中的每个人,无论他们是否启用了视频。这将使所有参与者并排在一起,包括你自己在主界面上的视频。 微软还为这个视图添加了新的主题和布局,为Skype的主要通话界面提供了一些亟需的定制功能。你将能够在扬声器视图、网格视图、大型图库、共同模式,甚至是内容视图之间进行选择--可以选择只显示启用视频的人。 Skype 新的彩色主题很快就会出现,包括按钮梯度,移动端改进的侧板,以及整个应用程序的流畅设计图标。没有头像的 Skype 用户也将获得彩色渐变,以便更容易区分聊天内容。 在团队博文中写道:“虽然我们喜欢设计上的变化,但我们知道它们还不够我们需要专注于性能,以使体验令人愉悦”。微软声称,它在 Android 版本的“关键场景”中的性能提高了 2000% 以上,在桌面版本的 Skype 中提高了 30%。 微软还承诺在未来的 Skype 变革中支持所有浏览器。Skype团队说:“我们相信,无论你使用什么浏览器或设备,Skype的体验都应该是无缝的、可访问的和可靠的,所以我们正在增加对所有浏览器的支持。我们希望确保无论你使用哪种设备、平台或浏览器,Skype都能给你带来美好的体验”。 其中一些改进现在已经上线,而其他改进将在未来几个月内推出。自定义通知声音是近期新功能的一部分,而新的TwinCam功能让你在通话中添加手机摄像头,似乎会在以后推出。 微软肯定是在关注Skype的广泛改进。这是微软自2014年开始调整Skype以来的最新一次重新设计,随后在2017年进行了类似Snapchat的设计,在2018年进行了另一次重新设计,干掉了类似Snapchat的激进变化,此后又对桌面和移动应用进行了大量修改。 【责任编辑:未丽燕 TEL:(010)68476606】

优秀的个人博客,低调大师

快速体验鸿蒙Liteos-A:IMX6ULL的QEMU系统(Windows版本)

1. 简介 QEMU可以模拟x86,也可以模拟各种ARM板子,还可以模拟各种外设。百问网对QEMU做了很多改进,支持更多硬件,支持更多GUI现实,让用户可以更有真实感地使用QEMU来模拟IMX6ULL板子。 1.1 100ASK-QEMU特点: 模拟网卡 模拟LCD显示功能 模拟led灯、按键 模拟at24cxx i2c存储芯片,直接可以通过用户态操作看到效果 模拟触摸屏(单点触摸) 后续会逐渐增加更多的模拟硬件模块 1.2 已经移植的系统 Linux 鸿蒙Liteos-A 2. 使用QEMU 2.1 下载 下载本GIT仓库: git clone https://gitee.com/weidongshan/qemu_image_for_imx6ull.git 也可以直接到文末下载完整的资源包! 如果你下载的是zip包,解压后目录名太长,会导致GUI界面无法显示。 把目录名改短即可。 2.2 体验Linux 双击运行env.bat, 在里面执行linux.bat即可启动Linux,输入root登录。 1. 体验LCD和触摸屏 执行如下命令: [root@qemu_imx6ul:/]# myfb-test /dev/fb0 // 在屏幕上画同心圆 [root@qemu_imx6ul:/]# ts_test // 可在开发板的LCD界面使用鼠标点击、画线 [root@qemu_imx6ul:/]# // 按ctrl+shift+c退出程序 2. 体验LED 执行如下命令,观察开发板上第1个LED: [root@qemu_imx6ul:~]# insmod 100ask_led.ko [root@qemu_imx6ul:~]# ls /dev/100ask_led0 /dev/100ask_led0 [root@qemu_imx6ul:~]# ledtest /dev/100ask_led0 on [root@qemu_imx6ul:~]# ledtest /dev/100ask_led0 off 3. 体验按键 执行如下命令,并在"设备管理器"中点击"buttons"按钮显示出按键的操作界面 [root@qemu_imx6ul:~]# insmod 100ask_led.ko // 如果前面执行过,这里不需要再次执行 [root@qemu_imx6ul:~]# cd button_driver_qemu/ [root@qemu_imx6ul:~/button_driver_qemu]# insmod button_drv.ko [root@qemu_imx6ul:~/button_driver_qemu]# insmod board_100ask_qemu_imx6ull.ko [root@qemu_imx6ul:~/button_driver_qemu]# ./button_led_test 4. 读写I2C EEPROM AT24C02 首先在“设备管理器”中打开at24c02的界面,然后执行以下命令测试: // 0x50是AT24C02的I2C设备地址 [root@qemu_imx6ul:~]# i2c_usr_test /dev/i2c-0 0x50 r 0 // 读地址0 data: , 0, 0x00 [root@qemu_imx6ul:~]# i2c_usr_test /dev/i2c-0 0x50 w 1 0x58 // 写地址1,写入0x58 效果如下: 5. 通过ssh登录开发板 本GIT仓库中,env.bat启动的是终端软件ConEmu,它比Windows命令行稍微好用点。 但是它不支持键盘的箭头,可以通过ssh登录开发板。 linux.bat中设置了端口转换,如下: 可以使用其他ssh软件,比如MobaXterm通过23端口远程登录开发板,操作更方便。 2.3 体验鸿蒙Liteos-A 双击运行env.bat, 在里面执行harmony_liteos.bat即可启动、进入Liteos-A。 1. 执行shell命令 执行help命令,可以看到支持的SHELL命令,如下: 2. 执行数码相框GUI程序 注意:必须用“./bin/digitpic”,不能用绝对路径“/bin/digitpic”注意:这个GUI程序是我们自己写得,很丑,与鸿蒙无关。 3. 退出程序 执行task命令确定进程号,然后执行“kill -9 PID”杀掉进程,比如: 3. 常见问题 3.1 不能放在中文目录下 否则会提示无法加载文件,比如: 3.2 目录名不能有空格 否则有如下提示: 3.3 目录名太长 如果你下载的是zip包,解压后目录名太长,会导致GUI界面无法显示。 把目录名改短即可。 3.4 ConEmu无法运行 系统原因,错误提示如下: 可以尝试运行另一个程序: 如果ConEmu程序都无法执行,直接双击harmony_liteos.bat或linux.bat,它使用DOS命令行作为终端,有乱码。 3.5 退出程序 注意:ctrl+c是退出QEMU,也就是退出Linux或Liteos-A。 要退出Linux中的当前程序:使用 ctrl+shift+c。 Liteos-A中没有当前程序,只能使用kill命令杀死进程。 3.6 鼠标无法移出开发板界面 当你的鼠标点击QEMU的GUI界面时,鼠标将无法移出这个GUI界面。 这时可以通过快捷键“Ctrl+Alt+g”把鼠标从GUI界面中退出来。 文章后续内容和相关附件可以点击下面的原文链接前往学习 原文链接:https://harmonyos.51cto.com/posts/4507#bkwz 想了解更多关于鸿蒙的内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区 https://harmonyos.51cto.com/#bkwz

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册