视频号直播:如何进一步降低功耗占用?

发表于 1年以前  | 总阅读数:696 次

一、背景

功耗优化一直是 app 性能优化中让人头疼的问题,尤其是在直播这种用户观看时长特别久的场景。怎样能在不影响主体验的前提下,进一步优化「iOS视频号直播的功耗占用」,本文给出了一个不太一样的答案。

二、问题

问题的起因是我们测试统计发现带有点赞的直播会比无点赞动画的直播 GPU 占用要高将近一倍,同时 FPS 差异也很大。高刷屏下,PerfDog 测试显示,有点赞情况下的大部分视频号直播居然是以60fps在跑,这导致了极高的GPU占用。

但我们根本没有60fps 这么高的直播流,且绝大部分直播流都只有30fps 而已,少部分也就最高60fps,怎么到了设备上就达到了60fps?而且这还是我们开启了强制低帧率UIViewAnimationOptionPreferredFramesPerSecond30后的效果,没开之前直接奔120fps 去了。

如下图所示 PerfDog 数据显示在 13 pro max上直播点赞期间 FPS 直奔120。

图1正常情况下,视频号直播里大部分主播开播流基本都是30fps 以内,也就是正常情况下我们只需要维持30fps 渲染,就能保持好流程的用户体验。

那为什么这里降帧后依旧会出现60fps 呢?经过一系列排查我们发现这是由于直播的点赞动画导致的高帧率,如果去掉动画后 FPS 就会回到正常情况下了,且 GPU 占用也有了明显下降。

这到底是怎么回事?我们是否可以降动画的帧率降低到某个值来去优化我们整体的 GPU 占用呢?

三、知识储备

本节主要介绍一些 iOS 动画和相关优化的基础背景知识,「如对此有一定了解的同学可略过到下一部分:第四节-优化方案。」

3.1、动画分类

在iOS中,大部分动画的本质就是根据输入的时间戳,返回对应属性的动画参数,从而移动图像,达到运动的效果。根据动画 api 实现方式的特点我们可以把动画 api 划分为如下几类:

UIView block animation

基于 「+[UIView animateWithDuration:delay:options:animations:completion:]」 动画api驱动的动画,特点是所有动画都在 animations block 里同步触发,可以方便的设置任何属性动画。

[UIView animateWithDuration:duration
                             delay:0
                           options:option
                        animations:^{
                            view.top -= offsetY;
                            view.left -= offsetX;
                        }
                        completion:completion];

CAAnimation

基于 「CAAnimation api」 直接触发提交的动画,例如:

CABasicAnimation *ani_position = [CABasicAnimation animationWithKeyPath:@"position"];
ani_position.fromValue = @(val.position.from);
ani_position.toValue = @(val.position.to);
[view.layer addAnimation:group forKey:key];

Timer

基于 「NSTimer/GCD」 触发的动画,例如定时去修改某个 imageView.image,使得它能定期变换的效果。基于 「CADisplayLink」 触发的动画,和基于 NSTimer 触发类似,只不过这个 timer 源是和渲染保持一致的,能够做到更流畅更贴合。比如我们要实现自定义的 UIScrollView 动画,就可以基于 CADisplayLink 来做。

UIViewPropertyAnimator

「UIViewPropertyAnimator」 是iOS10开始苹果推动的新的动画api,相比 UIView block animation 可以更灵活的控制动画的过程。

[UIViewPropertyAnimator runningPropertyAnimatorWithDuration:duration
                                     delay:0
                                   options:option
                                animations:^{
                                    view.top -= offsetY;
                                    view.left -= offsetX;
                                }
                                completion:completion];

3.2、动画渲染

iOS中的动画或者 UIView 的修改到底是怎么被渲染到屏幕上去的?

Core Animation Pipeline

iOS 的 UI 更新和动画操作都离不开 Core Animation 和 UIKit,他们的底层都是 QuartzCore,所有的 UI 刷新和动画提交都会打包成对应的 CA::Transaction 和 CAAnimation 对象并提交给 Render Server 去处理。

App 本身并不负责渲染,渲染是由独立的进程 Render Server 来负责的,Render Server 最终调用 -[AGXG14FamilyRenderContext drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:] 等 GPU 接口来完成 GPU 任务的提交,最终触发屏幕更新操作。

整体过程大概如下:

  1. App 处理事件,例如 touch 事件或者 displaylink timer 事件
  2. App 完成视图的 layout、图像 decode 等操作,并触发 CA::Transaction 提交
  3. Render Server 接收 App 提交的 Transction 和图片数据,Render Server 可直接跨进程访问 App 进程的位图内存资源,并最终触发 GPU 调用
  4. GPU 最终完成了图像的渲染并显示到屏幕 Display

Render Server

如下图所示,最终的上屏任务提交操作是由 Render Server 也即 backboardd 进程来最终触发的。

❝在 iOS 中 Render Server 通常指的是 backboardd 进程,backboardd 进程是一个与 SpringBoard 守护进程一起运行的守护进程。它在 iOS 6 中引入,旨在减轻 Springboard 的一些职责,主要是事件处理的职责。它主要负责把 touch 事件分发到 app 进程以及处理 app 进程触发的动画和UI更新操作。如上图所示,time profiler 里我们能清晰看到 backboardd 进程在处理来自 app 进程的图像提交操作。

微信直播之前就遇到过好几次 Render Server 命中了 gpu io fence 导致系统全局卡死的问题,如下图 ips 文件日志所示:

Render Loop

Render Loop 是包括了从 app 到 Render Server 再最终到屏幕的一系列任务触发,刷新,更新与提交,直到上屏的一系列过程,是对渲染管道的进一步封装,类似于一套 runloop 循环机制,能随时的处理输入和输出。

动画渲染

当我们调用-[UIView animateWithDuration:animations:] api触发动画后,整体动画渲染过程如下图3步所示:

帧率

帧率即 FPS(frames per second),每秒渲染了多少帧,正常情况下只要我们定期提交一次 opengl 上屏[curContext presentRenderbuffer:GL_RENDERBUFFER] 就会触发一帧的上屏操作,这就回导致 FPS 发生变化,也最终影响了 app 的性能占用。

FPS 越高对于游戏等高清视频效果就更细腻更好,但是并不是所有情况都需要高 FPS,部分情况下高 FPS 反而导致了无用的功耗但并没有带来更好的体验。

屏幕刷新率

对于 iOS15/iPhone 13以前的设备,屏幕是固定的刷新率,在这之后 iPhone 13和 iPad Pro 后引入了高刷屏,并且支持了动态刷新率。

对于直播场景 FPS 有3个:

  1. 视频流 FPS
  2. Render Server FPS
  3. 屏幕 FPS

对于非可变刷新率的屏幕,我们可以尽可能减少 GPU 的帧率(即 Render Server 提交的 FPS)来达到降低 GPU 功耗的目的,对于可变刷新率的屏幕,那只要减少了 GPU 帧率就自然而然也减少了屏幕的刷新率,使得屏幕和 GPU 功耗都下降了。

在我们遇到的问题中,我们的视频流 FPS 是25,那么我们预期的最终 GPU FPS 和屏幕 FPS 理应同理也是接近25才是,而这里却达到了60fps,说明了有重复的内容帧一直被 Render Server 重复的复制并提交给 GPU,导致了画质细节没有增加,但频繁的拷贝渲染造成了更高的 GPU 占用。这就是我们的问题所在。

3.3、动画降帧

结合上文,我们要解决直播帧率异常升高的问题,就需要解决点赞动画的高帧率问题。很幸运,苹果在 iOS15提供了一个 CAAnimation 的 api,即-[CAAnimation preferredFrameRateRange],它接受3个参数分别指定minimum 帧率,maximum 帧率,以及 preferred 帧率,基于这个api我们可以对于 CAAnimation 动画设置帧率,苹果的建议是把动画分为了如下几档:

CAAnimation 降帧原理

iOS15开始苹果引入了 CAFrameRateRange 相关 api 来供 app 去设置 CADisplayLink 和 CAAnimation 的preferredFrameRateRange,以方便调节帧率,达到在高刷机上能进一步降低功耗的目的。那它又是如何工作的呢?

首先需要明确 iOS15后 CAAnimation 和 CADisplayLink 的帧率控制底层都是一致的,也就是都是 CA::Display::DisplayLinkItem 来驱动触发的。而动画的本质就是根据时间的输入来得到对应的动画 fraction 并触发对应进度的动画修改,再提交上屏完成修改。具体而言,我们以 UIScrollView的 setContentOffset:animated 动画为例:

setContentOffset:animated 动画机制

当我们触发[scrollView setContentOffset:CGPointMake(120,0) animated:YES]后,会触发创建一个 UIScrollViewAnimation 的实例对象(UIAnimation的子类),接下来会调用 UIUpdateSequenceInsertItem 将这个动画实例注册到当前的 UIUpdateCycle 循环中。

UIUpdateCycle 负责根据设备的 CADisplay 屏幕刷新率和设置动态效果里设置的是否限制帧速率来抉择出到底是以120hz还是60hz来驱动 UIUpdateCycle 循环的触发,当以120hz触发动画循环时,接着会在每8ms间触发一次_UIUpdateSequenceRun,来执行 UIScrollViewAnimation 的动画 progress 计算操作,如图:

图9每次触发触发_UIUpdateSequenceRun 时,会向 UIScrollViewAnimation 请求[UIAnimation fractionForTime:]来返回对应时间戳的 contentOffset 和 progress,然后触发修改 contentOffset,最终接近目标 contentOffset 后就完成了完整的动画。

CAFrameRateRange

当我们设置 CAAnimation 的 preferredFrameRateRange 后,QuartzCore 会将 CAFrameRateRange 转为CAFrameIntervalRange 结构,并最终尝试触发 Render Server 在指定帧间隔内渲染每一帧动画,如下图:

帧率变化探索

所有的帧提交操作最终都是在 Render Server 触发的,也就是只有从 Render Server 统计FPS才是最终的实际 FPS,那我们要怎么统计呢?QuartzCore 提供了一个系统级的面板工具,它可以很方便的显示当前的 QuartzCore 渲染信息,包括fps,frame duration等一应俱全。

图11我们可以在越狱后给 app 自签名 com.apple.QuartzCore.debug 这个 entitlement 后,再调用如下代码所示的私有 api 即可全局打开这个面板,可以方便的在手机端查看 Render Server 上的实际 FPS。

extern "C" {
int CARenderServerGetDebugOption(mach_port_t port, int key);
int CARenderServerGetDebugValue(mach_port_t port, int key);
void CARenderServerSetDebugOption(mach_port_t port, int key, int value);
void CARenderServerSetDebugValue(mach_port_t port, int key, int value);
}

由于以上能力无法在非越狱设备上开启,所以实际上我们无法检测 app 在任意时刻的 FPS 变化情况。不过经过分析,我们发现只要触发了以下行为就可能代表要帧率要变化了,如下:

  1. 在设置->动态效果里开启或关闭“限制帧速率”

❝修改限制帧速率会触发系统抛出 com.apple.CoreAnimation.CAWindowServer.DisplayChanged 的通知,QuartCore 会在启动时注册这个通知,并收到通知后通过 mach port 通信获取当前注册的帧速率值,以动态修改 displaylink 的回调频次;

  1. 直接通过 opengl/metal api 提交一帧画面给 Render Server
  2. 触发 CA::Transaction 对象的提交

❝除了触发动画提交,触发 view property 提交变更外,甚至创建 view 也会导致 source0触发一次,如下图:

通过调试分析,我们大概清楚了 iOS15引入的 CAAnimation 的preferredFrameRateRange 工作机制,如下图所示:

我们只要修改 UIUpdateSequenceRun 的回调频率,也就是-[UIAnimator _advanceAnimationsOnScreenWithIdentifier:withTimestamp:] 的回调频次我们就能控制部分系统动画的帧率,强制调节他的执行频次,或者我们通过模拟系统设置->动态效果->限制帧速率的实现方式,主动调用 -[CADisplay overrideMinimumFrameDuration:]传入4便可将 UIAnimator 的刷新率调节为240/4=60hz,或者传入8即可将系统动画刷新率调节为240/8=30hz。

基于以上研究,理论上我们可以尝试调用私有 api 来全局控制 CADisplay 的刷新率,来进一步降低性能占用,但是由于 Render Server 是在其他进程,我们还是无法控制 Render Server 的刷新率,并且私有 api 会导致 app 被拒审,所以我们最终依旧只能改造部分系统动画实现以继续基于 CAAnimation api 去优化帧率。

四、优化方案

从 iOS15开始苹果新增加了 preferredFrameRateRange api 可用于设置相应动画或timer的刷新频率,我们就可以基于该方案去改造相应动画即可。

@property CAFrameRateRange preferredFrameRateRange
    API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0));

但新的问题又来了,系统仅给 CAAnimation 和 CADisplayLink 的 api 提供了动态修改帧率的操作,但是在我们直播场景中,一共有如下几种场景的动画提交:

  1. UIView block 动画
  2. UIScrollView scroll 动画
  3. NSTimer 动画
  4. CAAnimation

除了4我们可以直接修改为 iOS15支持的 preferredFrameRateRange api 外,其它几个我们要怎么解决呢?

针对以上1~3点我们分别做如下处理:

4.1 UIView block 动画

通过分析+[UIView animateWithDuration:delay:options:animations:completion:] 调用,我们发现 animations block 里的 property animation 会被同步的创建为 CAAnimation 对象,如图所示:

图14

那我们是否可以 hook CAAnimation 然后寻找时机设置它的 preferredFrameRateRange 以达到降帧的目的?很遗憾,不行,因为这个 api 触发的动画不会去触发对应的 setter 与 getter 去读取新修改的值,而是被覆盖为一个默认值,导致无法降帧。

再进一步调试发现与UIViewPropertyAnimator 里是有主动 setPreferredFrameRateRange:的操作,那是否可以从这里入手?

经过验证,果然可行,于是我们可以将所有的 UIView block animation 动画都无缝替换为新方案后,即可实现自动降帧随意灵活控制的目的了,部分代码如下:

  if (@available(iOS 15.0, *)) {
        setFrameRateLevel(level);
        [UIViewPropertyAnimator runningPropertyAnimatorWithDuration:duration
                                                              delay:delay
                                                            options:options
                                                         animations:animations
completion:^(UIViewAnimatingPosition finalPosition) {
                                                             if (completion) {
                                                                 completion(YES);
                                                             }
                                                         }];
        clearFrameRateLevel();
    } else {
        if (level != MMAnimationFrameRateLevelNone) {
            if (level <= MMAnimationFrameRateLevelMedium)
                options |= UIViewAnimationOptionPreferredFramesPerSecond30;
        }
        [self animateWithDuration:duration delay:delay options:options animations:animations completion:completion];
    }

新的接口可以无缝替换原有的+[UIView animateWithDuration:delay:options:animations:completion:] 调用,可对所有系统实现降帧调节优化,极大的方便了业务开发同学在不同场景中选择合适的动画帧率,以达到效果和耗电的平衡。

4.2 UIScrollView 动画

经过上文的分析我们发现 UIScrollView setContentOffset 的动画是基于系统_UIUpdateTarget 机制来驱动的,由于对应的回调是私有 api 触发的,所以我们无法直接调节它的帧率,于是我们干脆自己实现一个基于 CADisplayLink 驱动的 setContentOffset 滑动动画即可解决问题。即:创建一个CADisplayLink对象,指定我们需要的 preferredFrameRateRange 帧率,然后在每一帧回调时,根据当前的时间戳计算出当前需要设置的 contentOffset 值,直到最终达到了指定的动画 duration 时间后,我们再把 contentOffset 调整为目标值,即可。

主体代码大致如下:

- (void)tt_contentOffset:(CGPoint)contentOffset duration:(CFTimeInterval)duration {
    self.duration = duration;
    self.deltaContentOffset = CGPointMinus(contentOffset, self.scrollView.contentOffset);
    if (!self.displayLink) {
        self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateContentOffset:)];
        if (@available(iOS 15.0, *)) {
            self.displayLink.preferredFrameRateRange = CAFrameRateRangeMake(15, 24, 0);
        } else {
            self.displayLink.preferredFramesPerSecond = 30;
        }
        [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    } else {
        self.displayLink.paused = NO;
    }
}
- (void)tt_onDisplayLink:(CADisplayLink *)displayLink {
    if (self.beginTime == 0.0) {
        self.beginTime = self.displayLink.timestamp;
        self.beginContentOffset = self.scrollView.contentOffset;
    } else {
        CFTimeInterval duration = displayLink.timestamp - self.beginTime;
        CGFloat percent = (CGFloat)(duration / self.duration);
        if (percent < 1.0) {
            CGFloat progress = (CGFloat)timingFunctionValue(self.timingFunction, percent);
            if (1 - progress < 0.001) {
                [self tt_stopAnimation];
            } else {
                [self tt_updateProgress:progress];
            }
        } else {
            [self tt_stopAnimation];
        }
    }
}

4.3 NSTimer 动画

根据苹果Explore UI animation hitches and the render loop 的说法,为了避免 vsync 信号和 timer 可能不同步的情形,我们直接用 CADisplayLink 来替换原先的 NSTimer,并在 CADisplayLink 回调里再触发对应的 UI 提交操作和动画即可。

这是因为:如下图所示,对于13 pro max 高刷屏设备而言,其 UI 动画的系统回调频次是240hz,渲染帧率是可变的可为0~120fps 之间,而常规的 NSTimer 是基于 RunLoop 触发回调的,RunLoop 的回调间隔可能只有几十 us,那么 Timer 的灵敏度远高于 DisplayLink,所以完全是有可能在2帧渲染之间,回调了一次 Timer,而最终导致可能会多触发了一帧的提交或一次渲染事件。所以我们采取 CADisplayLink 来替换 NSTimer,尽可能避免和 Display 不同步的渲染触发操作。

五、优化效果

按照苹果的建议 ,app 内容在没有频繁更新时,应该尽量降低 FPS 以平衡功耗占用,因为高刷必然带来更频繁的 GPU 任务提交,使得 GPU 占用提升。

并且 app 的刷新率是由所有内容的最高刷新率决定的,也就是高 FPS 的界面元素会导致整个屏幕全局 FPS 提升,只有适当平衡全局界面元素的 FPS 后,才能进一步降低不必要的性能消耗。

图16基于上述指导思想和优化方案,我们最终在视频号直播上验证测试如下:

先基于 「UIViewAnimationOptionPreferredFramesPerSecond30」 将直播点赞场景下的fps从高刷屏的120fps 降低到60fps,再基于 「UIViewPropertyAnimator」 将任意UIView block animation的帧率降低到30~48fps(最终全局稳定在40~50fps),帧率同比下降16%而 GPU 同比下降了26%~38%(在主场景和其他场景)。

并且由于我们的视频画面依旧是25fps的低帧率,所以此处降帧只是降低了 QuartzCore 的重复帧,而没有减少任何画面细节,最终本质上是无损的画面降帧。

另外,「在实验过程中调试」,进一步发现了一些很有用的环境变量,可以帮助我们更好的调试UI问题,如下:

环境变量 作用
setenv("QUARTZCORE_LOG_FILE", "stdout", 1); 输出 QuartzCore 日志到控制台
setenv("CA_PRINT_FRAME_INFO", "1", 1); 输出 frame 信息
setenv("CA_LOG_MEMORY_USAGE", "1", 1); 输出内存占用
setenv("CA_PRINT_ANIMATIONS", "1", 1); 输出动画信息
setenv("CA_ASSERT_MAIN_THREAD_TRANSACTIONS", "1", 1); 定位子线程 UI 行为

六、问题扩展

我们通过一些奇怪的绕过方式间接的实现了对所有基于 UIView block animation api 调用的动画以及 CAAnimation api 调用的动画都实现了动态降帧,这极大的改善了低帧率直播间的业务动画导致的 GPU 功耗占用问题。那对于高帧率直播间我们还能怎么解决呢?

基于苹果的文档帧率档位设置建议和我们的综合实践效果,我们对高帧率直播间采取了部分用户无明显感知的有损降级策略。即当检测到设备过热后,我们会将60fps 的直播流,以渲染端均匀丢帧的方式降帧到48fps,方案如下:

图18最终也一样取得了GPU 同比下降28%甚至更高的效果,有效减轻了过热时的系统负载和功耗,并且从肉眼上基本无法分辨出差异。

七、总结

本文在不影响现有用户体验和业务逻辑的情况下,通过扩展系统接口的能力与实验调试分析,「最终实现了一套 UI 动画的帧率调节方案。」 该方案得到的效果是:

  • 快速改造既有业务的所有动画,动态的控制各自的帧率;
  • 最终达到不影响效果的前提下,尽可能的降低了功耗;
  • 同时极大的减轻了业务开发同学适配多系统和改造动画的工作量。

该方案最终在「视频号直播上得到广泛应用,取得了较大的性能提升。」

参考

  • Optimize for variable refresh rate displays
  • Power down: Improve battery consumption
  • Explore UI animation hitches and the render loop
  • Demystify and eliminate hitches in the render phase
  • Advanced Graphics and Animations for iOS Apps

作者:rhythm
来自微信客户端团队

本文由哈喽比特于1年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/LKoGJylYfyk8iTXlvoW0gA

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237224次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8060次阅读
 目录