大小核异构架构(big.LITTLE architecture)

大小核异构架构(big.LITTLE architecture)

介绍

  为了避免多个等同的核心跑一个任务,只有一个Core在工作,其他Core开始空转,随着而来的就是功耗上升。大、小架构(big.LITTLEarchitecture)随之而生。
  大、小架构(big.LITTLE architecture)由大小核组成。
  “big coreswhich are optimized for performance and little coresoptimized for power efficiency。”
    大核心(big core)针对性能优化,它是个高性能、高功耗的核心。
      如 Cortex-A15、Cortex-A17、Cortex-A57 等。
    
小核心(LITTLE core)针对效率优化,它是个低性能、低功耗的核心。
      如 Cortex-A7、Cortex-A53 等。

(2017年,ARM推出了DynamIQ 架构作为 big.LITTLE 的继承和增强方案。DynamIQ架构支持混合搭配不同性能的 ARMCPU 核心(如Cortex-A75 和 Cortex-A55)。)

  启动高性能的Core,很闲的时候,切换到的低功耗的Core工作。

ARM处理器针对的多核采取了分层设计:

  将所有的高性能核放到一个叫big Cluster的蔟(Cluster)里,多个低功耗的放到另一个叫LittleCluster的蔟里,处理器中的每个Core都有自己独立的一级L1数据Cache和指令Cache,每个Cluster共享二级L2 Cache。为了保证多个Core运行时Cache和RAM中的数据相同,两个Cluster之间通过韩村一致性接口相连,不仅保证多个Core之间的高效通信,还通过检测电路,保证了多个Cache之间,Cache和RAM之间的数据一致性,避免程序运行时出错。

截图2

软件任务调度模型:

  CPU 迁移 (CPU Migration):早期模型。将一个大核和一个小核分为一组,同一时间只有一组中的单个核心处于活动状态。任务在配对的核心之间切换。这种方式不够灵活。
  
全局任务调度(Global Task Scheduling / big.LITTLE MP):现代主流方式。操作系统调度器能感知所有核心的负载和状态,可以直接将任务分配给任何最合适的大核或小核,所有核心可以同时在线工作。这种方式更加高效和灵活,能更好地利用所有计算资源。

big.LITTLE 架构带来的主要好处包括:

  • 显著降低功耗:将轻负载任务分配给高能效的小核处理,可以大幅节省电力。ARM 数据显示,在某些场景下可比同数量大核的传统设计节省高达 70%-75% 的功耗。
  • 提升能效与性能:在提供强劲峰值性能(大核)的同时,保证了极佳的整体能效(小核),实现了高性能与长续航的平衡。ARM称其在线程负载方面可提升 40% 的性能。
  • 延长电池续航:对移动设备至关重要,允许用户更长时间地使用设备而不必频繁充电。

了解CPU利用率

  “CPU受限”并不一定意味着CPU得到了充分利用。需要深入理解游戏业务和游戏引擎的线程本质。
  一般游戏至少有一个主线程和一个渲染线程,而游戏一般以单线程或双线程的来工作,可能会因单核上跑单个线程而出现瓶颈,并受到CPU的限制。

例如
用骁龙的Snapdragon Profiler在8核CPU平台,您可能会遇到CPU利用率指标报告约为12.5%(100% / 8核)。这看起来不像是这个游戏瓶颈的来源,但是仔细看看!

截图

通过骁龙的Snapdragon Profiler的CPU Utilization Realtime项看,不但没发现cpu瓶颈,在 Trace mode上看只有一个线程跑满,其他核心却是空闲。

截图2

线程和核心亲和力

  Kryo CPUs上的任务调度是在硬件层执行的。这种调度可以由操作系统通过平台API来控制,游戏开发者开放这一些选项配置来设置这些api,从而平衡功率和性能。
在骁龙平台可通过HeterogeneousCompute SDK控制任务执行和将任务映射到所需内核或内核类型。

sched_setaffinity() from sched.h是将线程映射到核core的另一种方法。

手动将线程映射到适当的核心往往会优于让Android的自动调度。

最佳实践:

  大核来处理对延迟足够敏感(latency-sensitive)且放在小核会过慢的任务,同时,应该尽可能利用小核。给定16ms (60FPS)的帧预算,利用SnapdragonProfiler分析,从而将合适的任务迁移到小核。

案例

  • 案例1:在大核上运行布料模拟解算器需要3毫秒,在小核上可能需要10毫秒。这个执行时间是可接受的(因为预算是16ms),这种任务就可以且应该转移到小内核。这既节省了功耗,又为为大核节省时间。
  • 案例2:音频通常应该被安排在一个小内核(最慢的)上,因为小核通常对于音频处理已经足够快了。
  • 案例3:渲染线程应安排在速度最快的大核上,以尽可能小化延迟并争取大化帧间隔;它是最不可能被中断的核心,处理速度最快。

电源功耗方面

  另一个需要注意的地方:过多或不必要的唤醒空闲的核,也会导致功耗增加。
  一种解决方案是将任务映射到同一个内核,而不使内核过载。
  骁龙移动大小核平台上,你可以从以下几个常见的维度出发:

任务调度维度

维度1:Core clustering核心簇:

  相同类型的核心并会编入同一个核心簇。大核性能好,能高效执行任务,但默认簇的选择由系统决定。因为内核根据CPU频率驱动程序提供的频率和电压进行调度,并非最优,所以这比下面两种方法差。

维度2:In-kernel switching or CPU migration内核切换或CPU迁移:

  一个大核心和一个小核心被配对成一个虚拟核心,但仅使用该虚拟核心中两个物理核心中的一个(哪个核心取决于调度)。这比核心簇提供了更高的效率,但要求两个cpu特性(core capabilities)一致。
参考:

Cpu特性的理解可参考:
https://support.huawei.com/enterprise/zh/doc/EDOC1100462771/3e5fd120

维度3:Global task scheduling全局任务调度:

  所有物理核心始终可用。全局任务调度器根据调度可将任务分配到任意核心组合上。调度器合理组合核心(可以部分核心、所有核心或任何组合上)来处理工作是它高效之本,而未使用的核心会自动关闭。这种方法没有核心配置要求。它可以更快地应对变化的负载,且比核心集群上的CPU频率驱动程序更精细的粒度上分配工作。

其他维度

维度4:对应平台提供的sdk设置。

  开发人员还可通过骁龙平台的PowerOptimization SDK设置电池模式来优化电源。该SDK允许开发人员根据游戏或任务的性能/功耗来设置电池模式:

  • 高效模式:实现接近最佳的性能和节能
  • 性能突发模式:在短时间内以最大频率支持所有内核。对于密集计算的突发来说,提高性能是很有用的
  • 保护模式:提供大约一半的系统峰值性能,可帮助低性能要求的应用程序
  • 窗口期模式:允许使用参数来设置相对于内核可以使用的最大频率的最小和最大频率百分比,从而对性能/功耗平衡进行微调
  • 自然振荡:将系统返回到默认状态

维度5:NEON Intrinsics和SIMD

  NEON Intrinsics是ARM架构下用于SIMD(单指令多数据)并行计算的C/C++内置函数接口。
  Arm Neon是面向Arm处理器的高级SIMD架构。NEON指令集为SIMD处理提供了一组专用寄存器。
  该指令集包括典型的SIMD操作,用于在Neon和通用寄存器之间移动数据,以及数据处理和类型转换。通过手工编码的汇编、内部函数或编译器的自动矢量化来有效使用Neon,可以为多媒体应用带来巨大的性能增益。高通的SIMD/FPU协处理器兼容Arm Neon指令集。

  有关Neon内部函数的更多信息,请参考https://developer . arm . com/architectures/instruction-sets/SIMD-ISAs/neon.

维度6:DSP和GPU接口

  一些对延迟不太敏感的逻辑可交给DSP。通常这比任何GPU回读更高效。

最佳实践

简要:

  • 让延迟敏感、繁重的线程(如渲染)跑在最快且可用的核心上。
  • 让其他线程(如音频)跑在最慢且可承载该任务的核心上。
  • 使用NEON Intrinsics
  • 将任务交给给DSP
  • 不要开放CPU端Vulkan内存分配器

避免单线程集中单核心导致CPU100%。

  密切关注您的游戏和任务系统的线程化特性,以避免在大多数其他核心空闲或未充分利用的情况下,单核心因线程而出现瓶颈。

  如Snapdragon Profiler的工具可使用Android跟踪用户标记来帮助识别有问题的区域,或者Snapdragon Profiler采样模式,可以生成所有内核中使用率最高的函数的火焰图。

避免磁盘I/O或阻塞操作在主/渲染线程上

  在Android上过度使用主/渲染线程可能导致“应用程序不响应”(ANR)错误——尤其是在使用磁盘I/O或阻塞操作时。

用Neon处理SIMD操作

  尽可能使用NEON Intrinsics。如果你正在使用第三方游戏引擎或中间件,尽可能添加Neon优化和启用。

使用大核处理计算密集型任务

  当任务需要大量计算工作时,最好使用大核。这有助于缓解单核上的瓶颈,并保持更加平缓的FPS。

使用小内核执行高能效任务

  运行游戏的大部分逻辑小核心可以带来更大的功耗优势、更长的电池寿命、更低的温度以及用户更长的游戏时间。

多线程游戏初始化

  游戏加载包含密集的内存申请和逻辑计算,这会导致终端用户等待很长时间。使用多线程来处理游戏加载可以减少加载时间并改善用户体验。

Vulkan

  • 最小化动态内存分配——理想情况下,来自Android启动时一次性请求所有内存,然后由应用程序管理。这避免了碎片化。
  • 不要开放CPU端的内存分配器——它的性能会低于默认的分配器。(然而,CPU端Vulkan分配器在开发/调试期间仍然有用)。

参考:

推荐阅读《Qualcomm®KryoTM CPU》
https://docs.qualcomm.com/bundle/publicresource/topics/80-78185-2/cpu.html?product=1601111740035277#kryo-cpu

《CPU性能优化:big little结构》
https://blog.csdn.net/fantasy_ARM9/article/details/131030361

《ARM的big.LITTLE架构》
https://blog.csdn.net/sinat_31608641/article/details/151364688

《性能优化(CPU优化技术)-NEON指令详解》可理解NEON Intrinsics
https://download.csdn.net/blog/column/12489912/136841581

posted @ 2025-11-05 22:02  昂流  阅读(10)  评论(0)    收藏  举报
//替换成自己路径的js文件 hhttp(s)://static.tctip.com/tctip-1.0.4.min.js