1172 -- 精 挑 细 选

本文介绍了一个程序设计案例,旨在从大量钢管中筛选出符合特定条件的一根:即最长、最细且编码最大。通过读取输入数据并进行多轮比较,最终输出符合条件的钢管编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

精 挑 细 选

Time Limit:1000MS  Memory Limit:65536K
Total Submit:38 Accepted:28

Description

小王是公司的仓库管理员,一天,他接到了这样一个任务:从仓库中找出一根钢管。这听起来不算什么,但是这根钢管的要求可真是让他犯难了,要求如下:
1、 这根钢管一定要是仓库中最长的;
2、 这根钢管一定要是最长的钢管中最细的;
3、 这根钢管一定要是符合前两条的钢管中编码最大的(每根钢管都有一个互不相同的编码,越大表示生产日期越近)。
相关的资料到是有,可是,手工从几百份钢管材料中选出符合要求的那根……
要不,还是请你编写个程序来帮他解决这个问题吧。

Input

第一行是一个整数N(N<=10)表示测试数据的组数)
每组测试数据的第一行 有一个整数m(m<=1000),表示仓库中所有钢管的数量,
之后m行,每行三个整数,分别表示一根钢管的长度(以毫米为单位)、直径(以毫米为单位)和编码(一个9位整数)。

Output

对应每组测试数据的输出只有一个9位整数,表示选出的那根钢管的编码,
每个输出占一行

Sample Input

2
2
2000 30 123456789
2000 20 987654321
4
3000 50 872198442
3000 45 752498124
2000 60 765128742
3000 45 652278122

Sample Output

987654321
752498124

Source

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AK1172 {
    /// <summary>
    /// 实际上这题就是简单的结构体排序,但是这样写也可以
    /// </summary>
    class Program {
        static void Main(string[] args) {
            int n = int.Parse(Console.ReadLine());
            while (n-- > 0) {
                int m = int.Parse(Console.ReadLine());
                int[] a = new int[1001], b = new int[1001], c = new int[1001];
                for (int i = 0; i < m; i++) {
                    string[] sb = Console.ReadLine().Split();
                    a[i] = int.Parse(sb[0]);
                    b[i] = int.Parse(sb[1]);
                    c[i] = int.Parse(sb[2]);
                }
                int max = 0, min = 1000000, mmax = 0;
                for (int i = 0; i < m; i++) if (a[i] > max) max = a[i];//先找到最长的
                for (int j = 0; j < m; j++) if (a[j] == max && b[j] < min) min = b[j];//然后找到最长中的最细的
                for (int i = 0; i < m; i++) if (a[i] == max && b[i] == min && c[i] > mmax) mmax = c[i];//然后找到最长中的最细的编码最大的
                Console.WriteLine(mmax);
            }
        }
    }
}


3、uifirst的优化⼿段 3.1 ⼿段A-运⾏队列任务的优先取 uifirst的优化对象基本都是cfs线程,这类线程有⼀个特点,就是择⼀个cpu后,先是放到cpu对应的运⾏队列上,然后等待被调度到,因此会出现调度时延的问题。如下: 图片: https://odocs.myoas.com/uploader/f/J6Sz2Prolvglwu6p.png?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE3NDE4NTEyOTQsImZpbGVHVUlEIjoicVZ0eXRqdHJ2OGtXM3ZqUSIsImlhdCI6MTc0MTg1MDY5NCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjozMjU4NjV9.348PeUOiyT8aGuz2nynlM1IcuJU_BqdGipzxCzN-yFg 3.1.1 uifirst 3.0 - 链表pick uifirst 3.0,在每个cpu的运⾏队列中,增加成员 list_head *ux_thread_list,凡是挂⼊运⾏队列的ux线程,都会加⼊这个链表。在每⼀次调度器择到下⼀个待执⾏的任务A时,我们都会从ux_thread_list中出ux线程,替代掉任务A。关键调⽤: pick_ux_1 thread(rq, &p, &se); 3.1.2 uifirst 4.0 - 虚拟补偿 uifirst 4.0,基本上只使⽤虚拟补偿的⽅式。cfs线程挂⼊cpu的运⾏队列时,会加⼊红⿊树中,每个线程拥有虚拟时间的概念,⽤来决定线程挂在红⿊树中的位置,⽽原⽣的cfs调度器,优先择红⿊树最左端的节点,作为下⼀个执⾏的线程。利⽤这⼀点,在唤醒时(从sleep、blocked状态返回),有机会对ux线程,进⾏更多的虚拟时间补偿,使ux线程在⼀定时间内,基本保证在红⿊树最左端。关键调⽤: place_entity_adjust_ux_task(cfs_rq, se, initial); 在打开组调度的版本(kernel-5.10 及以后)上,恢复到了链表的方式。原因是因为组调度(CONFIG_FAIR_GROUP_SCHED)的组的概念会使得虚拟补偿被弱化。 3.2 ⼿段B-锁竞争队列的优先排序6 uifirst对于ux线程的锁竞争⽅⾯,有两点调度优化,⽬前包含mutex、rwsem、futex: (1)将持锁的owner动态提升为ux,释放锁后将取消ux身份。关键调⽤: mutex_set_inherit_ux(lock, current); mutex_unset_inherit_ux(lock, current); (2)ux线程第⼀时间拿不到锁,挂⼊等待链表时,插⼊到其它等锁线程的前⾯。关键调⽤: mutex_list_add(current, &waiter->list, list, lock); PS:由于⾕歌GKI及ART修改限制,futex将在coloros 11.3上取消,理论上讲,从根源减少锁竞争才是正道! 3.3 ⼿段C-择⾼算⼒CPU uifirst对ux线程(主要是重载类型),在核时更倾向于择⼤核。关键调⽤: set_ux_task_to_prefer_cpu(p, &best_energy_cpu); slide_set_task_cpu(p, &best_energy_cpu); PS:择⼤核会对功耗造成影响,因此需要指定场景,⽬前主要是启动场景、滑动场景。 3.4 ⼿段D-适时提频 滑动期间,对于ux线程,会采⽤更激进的提频⽅式,在input boost⽅案中实现。关键调⽤: flag |= (SCHED_CPUFREQ_WALT | SCHED_1 CPUFREQ_BOOST);
最新发布
03-14
<think>嗯,用户让我介绍一下UIFirst的优化手段,特别是四个部分:运行队列任务的优先取、锁竞争队列的优先排序、择高算力CPU和适时提频。我需要先理解每个部分的具体内容,再组织成清晰的解释。 首先,用户提供的资料比较详,每个优化手段都有子项,比如3.1分为3.0和4.0版本的不同实现,还有后面的锁竞争、核和提频。我需要确保每个部分都覆盖到,并且用用户能理解的语言解释技术节。 在3.1运行队列任务优先取中,用户提到了链表pick和虚拟补偿两种方法。需要解释这两种方法的工作原理,以及为什么在UIFirst 4.0中又回到了链表方式。可能用户对背后的原因感兴趣,比如组调度的影响,所以这里需要说明清楚。 然后是锁竞争队列的优化,这里提到了动态提升持锁线程为UX,以及将UX线程插入等待队列前面。这部分需要解释为什么这样做能优化锁竞争,以及提到的GKI和ART修改限制的影响,可能用户关心兼容性和未来方向。 关于择高算力CPU,需要强调UX线程如何被调度到大核,以及功耗的权衡,特别是应用场景如启动和滑动,这里需要举例说明。 适时提频部分,提到input boost方案中的激进提频,要解释在滑动期间如何通过提频来保证流畅性,同时提到关键函数调用。 用户可能希望了解这些优化手段如何共同作用提升系统性能,同时存在的限制或权衡。例如,虚拟补偿在组调度下效果减弱,所以回到链表方式,这可能是因为组调度改变了红黑树的结构,导致补偿不够有效。需要用简单的话解释这点。 另外,用户提供的资料中有一些代码调用,如pick_ux_1和place_entity_adjust_ux_task,可能需要简要说明这些函数的作用,但不需要深入代码节,保持解释在概念层面。 还要注意用户之前的问题是关于UX节点的,现在转向优化手段,可能需要保持结构一致,分点清晰,使用标题和子标题帮助阅读。需要确保每个优化手段都有功能描述、实现原理、关键调用和注意事项。 最后,总结部分需要概括所有优化手段的共同目标,以及实际应用中的权衡,比如性能与功耗的平衡,避免滥用导致系统不稳定等。用户可能关心如何在实际开发中应用这些优化,或者遇到问题时的解决方法,但根据问题,主要是介绍性质,所以保持解释全面即可。</think>### 关于“UIFirst优化手段”详解 --- #### **3.1 手段A-运行队列任务的优先取** **核心问题**:CFS调度器默认将线程挂入红黑树队列,通过虚拟时间排序择最左端线程执行,导致UX线程可能因调度延迟影响实时性。UIFirst通过以下方式优化: --- ##### **3.1.1 UIFirst 3.0 - 链表PICK** - **实现原理**: 在每个CPU的运行队列(`rq`)中新增`ux_thread_list`链表,所有挂入运行队列的UX线程会被同时加入该链表。 调度器择下一个任务时,优先从链表中提取UX线程,覆盖原本中的非UX线程。 - **关键调用**: ```c pick_ux_1 thread(rq, &p, &se); // 从ux_thread_list中UX线程 ``` - **优点**: 直接绕过红黑树排序,确保UX线程快速被调度。 - **缺点**: 链表遍历可能增加调度开销,且未考虑线程优先级差异。 --- ##### **3.1.2 UIFirst 4.0 - 虚拟补偿** - **实现原理**: UX线程唤醒时(从阻塞/睡眠状态恢复),对其虚拟时间(`vruntime`)进行补偿,使其在红黑树中左移,从而被优先中。 例如: ```c place_entity_adjust_ux_task(cfs_rq, se, initial); // 调整UX线程的vruntime ``` - **优点**: 兼容CFS原生逻辑,减少侵入性修改。 - **限制**: 在开启组调度(`CONFIG_FAIR_GROUP_SCHED`)的内核中,组内线程共享虚拟时间,导致补偿效果被稀释。 **因此,5.10+内核版本恢复链表PICK方式**。 --- #### **3.2 手段B-锁竞争队列的优先排序** **核心目标**:减少UX线程因锁竞争导致的阻塞延迟,覆盖`mutex`、`rwsem`、`futex`三种锁类型。 ##### **3.2.1 持锁线程动态提升为UX** - **实现原理**: 当非UX线程持有锁时,若被UX线程争抢,则持锁线程临时提升为UX优先级,释放锁后恢复原身份。 ```c mutex_set_inherit_ux(lock, current); // 持锁时提升为UX mutex_unset_inherit_ux(lock, current); // 释放锁后取消UX ``` - **效果**: 加速持锁线程执行,缩短UX线程等待时间。 --- ##### **3.2.2 等待队列插队** - **实现原理**: UX线程争锁失败时,直接插入等待队列头部,优先被唤醒。 ```c mutex_list_add(current, &waiter->list, list, lock); // 插队到等待队列前端 ``` - **限制**: Google GKI和ART框架限制了对`futex`的修改,因此ColorOS 11.3+版本移除了对`futex`的优化。 **建议**:从代码设计层面减少锁竞争(如无锁结构或粒度锁)。 --- #### **3.3 手段C-择高算力CPU** **核心目标**:将重载型UX线程(如ux=2)优先绑定到大核,提升计算效率。 - **实现原理**: 在核逻辑中,为UX线程标记偏好大核(如ARM的Cortex-X系列)。 ```c set_ux_task_to_prefer_cpu(p, &best_energy_cpu); // 择高性能CPU slide_set_task_cpu(p, &best_energy_cpu); // 滑动场景特殊处理 ``` - **适用场景**: 应用启动、界面滑动等瞬时高负载场景。 - **代价**: 可能增加功耗,需结合功耗策略动态平衡。 --- #### **3.4 手段D-适时提频** **核心目标**:在用户交互敏感期(如滑动)主动提升CPU频率,保障UX线程执行速度。 - **实现原理**: 集成到`input boost`框架中,检测到滑动事件时,为UX线程关联的CPU触发激进提频。 ```c flag |= (SCHED_CPUFREQ_WALT | SCHED_CPUFREQ_BOOST); // 标志位触发提频 ``` - **效果**: 降低帧渲染延迟,提升滑动流畅度。 - **风险**: 高频运行可能加剧发热,需限制提频持续时间和场景。 --- ### **总结与注意事项** 1. **版本适配**: - 链表PICK(3.0)适用于简单场景,虚拟补偿(4.0)需内核未启用组调度。 - 锁优化需谨慎适配Android框架限制。 2. **性能与功耗平衡**: - 大核绑定和提频可能导致功耗上升,需结合实际场景动态调节。 3. **最佳实践**: - 优先使用场景节点(如滑动、启动)自动触发优化,避免手动标记滥用。 - 监控`/proc/sched_assist/debug`节点验证策略生效。 --- ### **技术演进趋势** - **虚拟补偿的回归**:组调度普及后,链表方式可能成为主流。 - **锁竞争优化**:逐步转向无锁设计,减少对调度器的依赖。 - **AI预测**:未来可能结合负载预测算法,动态预分配CPU资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值