当前位置: 首页 > news >正文

【操作系统】操作系统IO技术底层机制和ZeroCopy

1.DMA技术详解

(1)应用程序 从 磁盘读写数据 的时序图(未用DMA技术前)

在这里插入图片描述

(2)什么是DMA 技术 (Direct Memory Access)

  • 直接内存访问,直接内存访问是计算机科学中的一种内存访问技术。
  • DMA之前:要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,利用中断技术。
  • 允许某些硬件系统能够独立于CPU直接读写操作系统的内存,不需要中处理器(CPU)介入处理。
  • 数据传输操作在一个DM控制器(DMAC)的控制下进行,在传输过程中CPU可以继续进行其他的工作。
  • 在大部分时间CPU和I/O操作都处于并行状态,系统的效率更高。

在这里插入图片描述

(3)应用程序的读写数据

在这里插入图片描述

  • 读本地磁盘

    • 操作系统检查内存缓冲区读取,如果存在则直接把内核空间的数据copy到用户空间(CPU负责),应用程序即可使用。

    • 上步没数据,则从磁盘中读取到内核缓冲(DMA负责),再把内核空间的数据copy到用户空间(CPU负责),应用程序即可使用

    • 硬盘->内核缓冲区->用户缓冲区

  • 写操作本地磁盘

    • 根据操作系统的写入方式不一样,buffer IO 和 direct IO ,写入磁盘时机不一样。
    • buffer IO
      • 应用程序把数据从用户空间copy到内核空间的缓冲区(CPU负责),再把内核缓冲区的数据写到磁盘(DMA负责)。
    • direct IO
      • 应用程序把数据直接从用户态地址空间写入到磁盘中,直接跳过内核空间缓冲区。
      • 减少操作系统缓冲区和用户地址空间的拷贝次数,降低了CPU和内存开销。
    • 用户缓冲区->内核缓冲区->硬盘
  • 读网络数据

    • 网卡Socket(类似磁盘)中读取客户端发送的数据到内核空间(DMA负责)。
    • 把内核空间的数据copy到用户空间(CPU负责),然后应用程序即可使用。
  • 写网络数据

    • 用户缓冲区中的数据copy到内核缓冲区的Socket Buffer 中(CPU负责)
    • 将内核空间中的Socket Buffer 拷贝到Socket协议栈(网卡设备)进行传输(DMA负责)

(4)DMA的工作总结

  • 从磁盘的缓冲区到内核缓冲区的拷贝工作。
  • 从网卡设备到内核的socket buffer 的拷贝工作。
  • 从内核缓冲区到磁盘缓冲区的拷贝工作。
  • 从内核的socket buffer到网卡设备的拷贝工作。
  • 注意:内核缓冲区到用户缓冲区之间的拷贝工作仍然由CPU负责

(5)DMA技术带来的性能损耗

在这里插入图片描述

  • 上图应用程序从磁盘读取数据发送到网络上的损耗,程序需要两个命令 先read读取,再write写出
  • 四次内核态和用户态的切换
  • 四次缓冲区的拷贝(2次DMA拷贝、2次CPU拷贝)
    • 读取:磁盘缓冲区到内核缓冲区(DMA)
    • 读取:内核缓冲区到用户缓冲区(CPU)
    • 写出:用户缓冲区到内核缓冲区Socket Buffer(CPU)
    • 写出:内核缓冲区的Socket Buffer到网卡设备(DMA)

为了解决这种性能的损耗所以就诞生了零拷贝。

2.ZeroCopy零拷贝技术简介

(1)什么是零拷贝ZeroCopy

​ 减少不必要的内核缓冲区跟用户缓冲区之间的拷贝工作,从而减少CPU的开销和减少kernel和user模式的上下文切换,达到性能的提升。从磁盘中读取文件通过网络发送出去,只需要拷贝2\3次和2\4的内核态和用户态的切换即可。

ZeroCopy技术实现方式有两种(内核态和用户态切换次数不一样)

  • 方式一:mmap+write
  • 方式二:sendfile

(2)ZeroCopy的实现底层 mmap + write

  • 操作系统都使用虚拟内存,虚拟地址通过多级页表映射物理地址。

  • 多个虚拟内存可以指向同一个物理地址,虚拟内存的总空间远大于物理内存空间。

  • 如果把内核空间和用户空间的虚拟地址映射到同一个物理地址,就不需要来回复制数据。

  • mmap系统调用函数会直接把内核缓冲区的数据映射到用户空间,内核空间和用户空间就不需要在进行数据拷贝的操作了,节省了CPU开销。

  • mmap()负责读取,write()负责写出

  • 执行流程

    • 应用程序先调用mmap()方法,将数据从磁盘拷贝到内核缓冲区,返回结束(DMA负责)。在调用write(),内核缓冲区的数据直接拷贝到内核socket buffer (CPU负责),然后把内核缓冲区的Socket Buffer 给直接拷贝给Socket协议线,即网卡设备中,返回结束(DMA负责)

在这里插入图片描述

  • 采用mmap之后,CPU用户态和内核态上下文切换依旧是4次和全程有3次数据拷贝
  • 2次DMA拷贝、1次CPU拷贝、4次内核态用户态切换,减少了1次CPU拷贝

(3)ZeroCopy的实现底层 sendfile

  • Linux kernal 2.1新增发送文件的系统调用函数sendfile()。
  • 执行流程
    • 替代read()和write()两个系统调用,减少一次系统调用,即减少2次CPU上下文切换的开销,调用sendfile(),从磁盘读取到内核缓冲区,然后直接把内核缓冲区的数据拷贝到socket buffer缓冲区里,再把内核缓冲区的SocketBuffer给直接拷贝给Socket协议栈,即网卡设备中(DMA负责)。

在这里插入图片描述

  • 采用sendfile后,CPU用户态和内核态上下文切换是2次 和 全程3次的数据拷贝,2次DMA拷贝、1次的CPU拷贝、2次内核态用户态切换。
  • Linux 2.4+ 版本之后改进sendfile,利用DMA Gather(带有收集功能的DMA),变成了真正的零拷贝(没有CPU Copy)
    • 应用程序先调用sendfile()方法,将数据从磁盘拷贝到内核缓冲区(DMA负责)

    • 把内存地址、偏移量的缓冲区fd描述符拷贝到Socket Buffer中去 拷贝很少的数据,可忽略

      • 本质和虚拟内存的解决方法思路一样,就是内存地址的记录
    • 然后把内核缓冲区的Socket Buffer给直接拷贝给Socket协议栈 即网卡设备中,返回结束(DMA负责)

在这里插入图片描述

3.Java和主流中间件里的零拷贝技术

(1)Java中有哪些零拷贝技术

  • Java NIO对mmap的实现 fileChannel.map()
  • Java NIO对sendfile的实现 fileChannel.transferTo()fileChannel.transferFrom()

(2)什么是FileChannel

  • FileChannel是一个连接到文件的通道,可以通过文件通道读写文件,该常被用于搞笑的网络/文件的数据传输和大文件拷贝
  • 应用程序使用FileChannel写完以后,数据是在PageCache上的,操作系统不定时的把PageCache的数据写入到磁盘。为了避免宕机数据丢失,使用channel.force(true) 把文件相关的数据强制刷入磁盘上去。
  • 使用之前必须先打开它,但是无法直接new一个FileChannel。
  • 常规通过使用一个InputStream、OutputStream或者RandomAccessFile来获取一个FileChannel实例。
RandomAccessFile randomAccessFile = new RandomAccessFile("文件路径","rw");
FileChannel inChannel = randomAccessFile.getChannel();

(3)mmap方式实现

  • map方法,把文件映射成内存映射文件
  • MappedByteBuffer,是抽象类也是ByteBuffer的子类,具体实现子类是DirectByteBuffer,可被通道进行读写。
  • 一次map大小要限制在2G内,过大map会增加虚拟内存回收和重新分配的压力,直接报错。
  • FileChannel.java中的map对long size 进行了限制,不能大于Integer.MAX_VALUE,否则就报错

在这里插入图片描述

  • JDK层做限制是因为底层C++的类型,无符号int类型最大是2^31 -1, 2^31 -1 字节就是 2GB - 1B。
MappedByteBuffer map(int mode,long position,long size)
position:文件开始位置
size:映射文件区域大小
mode:访问该内存映射文件的方式,READ_ONLY(只读)、READ_WRITE(读写)、PRIVATE(创建一个读写副本)

(4)sendfile方式实现

  • fileChannel.transferTo(long postition,long count,WritableByteChannel target)
  • 将字节从此通道的文件传输到给定的可写入字节通道。
  • 返回值为真实拷贝的size,最大拷贝2G,超出2G的部分将丢弃。
position:文件中的位置,从此位置开始传输,必须非负数
count:要传输的最大字节数,必须非负数
target:目标通道
返回:实际已传输的字节数,可能为零
  • fileChannel.transferFrom(ReadableByteChannel src, long position, long count)
  • 将字节从给定的可读取字节通道传输到此通道的文件中
  • 对比 从源通道读取并将内容写入此通道的循环语句相比,此方法更高效
src:源通道
position:文件中的位置,从此位置开始传输,必须非负数
count:要传输的最大字节数, 必须非负数
返回:实际已传输的字节数,可能为零
  • transferFrom允许将一个通道连接到另一个通道,不需要在用户态和内核态来回复制,同时通道的内核态数据也无需复制,transferTo只有源为FileChannel才支持transfer这种搞笑的复制方式,其他如SocketChannel都不支持transfer模式。
  • 一般可以做FileChannel->FileChannel->FileChannel 和 FileChannel->SocketChannel的transfer零拷贝

4.文件IO性能对比实战

实现一个文件拷贝,对比不同IO方式性能差异,文件大小 200MB~5GB

编码实现:

  • 普通java的io流
  • 普通java的带buffer的io
  • 零拷贝实现之mmap的io
  • 零拷贝实现之sendfile的io

运行环境准备

  • Linux CentOS7.X
  • 安装JDK11 配置全局环境变量 vi /etc/profile
JAVA_HOME=/usr/local/jdk11
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH
  • 环境变量立刻生效

    • source /etc/profile
  • 查看安装情况 java -version

在这里插入图片描述

  • 准备1.34G测试文件

在这里插入图片描述

(1)普通java的io验证

public class IOTest {public static void main(String[] args) {String inputFilePath = args[0];String outputFilePath = args[1];long start = System.currentTimeMillis();try (FileInputStream fis = new FileInputStream(inputFilePath);FileOutputStream fos = new FileOutputStream(outputFilePath)) {byte[] buf = new byte[1];while(fis.read(buf) != -1){fos.write(buf);}} catch (IOException e) {e.printStackTrace();}long end = System.currentTimeMillis();System.out.println("普通IO耗时:"+(end-start));}
测试:java IOTest.java "/usr/local/music.zip" "/usr/local/io-music.zip"

在这里插入图片描述

(2)普通java的带buffer的io

public class BufferIOTest {public static void main(String[] args) {String inputFilePath = args[0];String outputFilePath = args[1];long start = System.currentTimeMillis();try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(inputFilePath));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outputFilePath))) {byte[] buf = new byte[1];while(bis.read(buf) != -1){bos.write(buf);}} catch (IOException e) {e.printStackTrace();}long end = System.currentTimeMillis();System.out.println("Buffer IO耗时:"+(end-start));}
}

在这里插入图片描述

(3)零拷贝实现之mmap的io

  • 一次 map 最大支持2GB,超过2GB会报错
public class MmapIOTest {public static void main(String[] args) {String inputFilePathStr = args[0];String outputFilePathStr = args[1];long start = System.currentTimeMillis();try (FileChannel channelIn = new FileInputStream(inputFilePathStr).getChannel();FileChannel channelOut = new RandomAccessFile(outputFilePathStr, "rw").getChannel()) {long size = channelIn.size();System.out.println("mappedFile:"+size);MappedByteBuffer mbbi = channelIn.map(FileChannel.MapMode.READ_ONLY, 0, size);MappedByteBuffer mbbo = channelOut.map(FileChannel.MapMode.READ_WRITE, 0, size);for (int i = 0; i < size; i++) {byte b = mbbi.get(i);mbbo.put(i,b);}} catch (Exception e) {e.printStackTrace();}long end = System.currentTimeMillis();System.out.println("mmap 零拷贝 IO 耗时:"+(end-start));}
}

在这里插入图片描述

(4)零拷贝实现之sendfile的io

  • 最大拷贝2G,超出2G的部分将丢弃,最终拷贝的文件大小只有2GB多点,超过2GB可以考虑多次执行
public class SendFileIOTest {public static void main(String[] args) {String inputFilePathStr = args[0];String outputFilePathStr = args[1];long start = System.currentTimeMillis();try (FileChannel channelIn = new FileInputStream(inputFilePathStr).getChannel();FileChannel channelOut = new FileOutputStream(outputFilePathStr).getChannel()) {// 代码一:针对小于2GB的问题,返回值为真实拷贝的size,最大拷贝2G,超出2G的部分将丢弃,最终拷贝文件大小只有2GB//channelIn.transferTo(0,channelIn.size(),channelOut);// 代码二:针对大于2GB的文件long size = channelIn.size();for (long left = size;left>0;){//transferSize所拷贝过去的真实长度,size - left 计算出下次要拷贝的位置long transferSize = channelIn.transferTo((size - left),left,channelOut);System.out.println("总大小:"+size+",拷贝大小:"+transferSize);//left剩余字节多少left = left - transferSize;}} catch (Exception e) {e.printStackTrace();}long end = System.currentTimeMillis();System.out.println("sendfile 零拷贝 IO 耗时:"+(end-start));}
}

在这里插入图片描述

(5)测试结果分析

  • 1~2GB的文件
  • 普通拷贝
    • 普通java的io流【慢】3973924秒
    • 普通java的带buffer的io【快】33196秒
  • 零拷贝
    • 零拷贝实现之mmap的io【快】7131秒
    • 零拷贝实现之sendfile的io【快】1784秒
  • 分析原因之前,我们先来了解一下局部性原理
局部性原理:指计算机在执行某个程序时,倾向于使用最近使用的数据
时间局部性:如果程序中的某条指令一旦被执行,则不久的将来该指令可能再次被执行
空间局部性:一旦程序访问了某个存储单元,在不久的将来附近的存储单元也有可能被访问
  • 普通的IO和Buffer IO,为什么带有Buffer的IO要比普通的IO性能高?
每次读取数据的时候,系统根据局部性原理,通过DMA会读入更多的数据到内核缓冲区里面
OS根据局部性原理会在一次read(),系统调用过程中预读更多的文件数据缓存在内核IO缓冲区中
当继续访问的文件数据在缓冲区中时便直接拷贝数据到进程缓冲区,避免了再次的抵消磁盘IO操作
OS已经帮减少磁盘IO操作次数,提高了性能
  • 两种零拷贝的方式对比
(1)sendfile无法在调用过程中修改数据,只适用于应用程序不需要对所访问数据进行处理修改情况,适合静态文件传输,MQ的Broker发送消息给消费者。适合大文件传输,2次上下文切换,最少2次数据拷贝。(2)mmap在mmap调用可以在应用程序中直接修改Page Cache中的数据,使用的是mmap+write两步。调用比sendfile成本高,但由于传统的拷贝方式,适用于多个线程以只读的方式同时访问同一个文件,mmap机制下多线程共享同一个物理内存空间,节约内存。适合小数据量续写,4次上下文切换,3次数据拷贝。

5.主流中间件中用到的ZeroCopy技术

(1)Nginx使用的是sendfile 零拷贝

  • WebServer处理静态页面请求时,是从磁盘中读取网页的内容,因为sendfile不能在应用程序中修改数据,所以最适合静态文件服务器或者是直接转发数据的代理服务器。

(2)rocketmq主要是mmap,也有小部分使用sendfile

  • rocketMQ在消息存盘和网络发送使用mmap, 单个CommitLog文件大小默认1GB
    • 要在用户进程内处理数据,然后再发送出去的话,用户空间和内核空间的数据传输就是不可避免的

(3)Kafka主要是sendfile,也有小部分使用mmap

  • kafka 在客户端和 broker 进行数据传输时,broker 使用 sendfile 系统调用,类似 【FileChannel.transferTo】 API,将磁盘文件读到 OS 内核缓冲区后,直接转到 socket buffer 进行网络发送,即 Linux 的 sendfile。
    中读取网页的内容,因为sendfile不能在应用程序中修改数据,所以最适合静态文件服务器或者是直接转发数据的代理服务器。

(2)rocketmq主要是mmap,也有小部分使用sendfile

  • rocketMQ在消息存盘和网络发送使用mmap, 单个CommitLog文件大小默认1GB
    • 要在用户进程内处理数据,然后再发送出去的话,用户空间和内核空间的数据传输就是不可避免的

(3)Kafka主要是sendfile,也有小部分使用mmap

  • kafka 在客户端和 broker 进行数据传输时,broker 使用 sendfile 系统调用,类似 【FileChannel.transferTo】 API,将磁盘文件读到 OS 内核缓冲区后,直接转到 socket buffer 进行网络发送,即 Linux 的 sendfile。

相关文章:

【操作系统】操作系统IO技术底层机制和ZeroCopy

1.DMA技术详解 &#xff08;1&#xff09;应用程序 从 磁盘读写数据 的时序图&#xff08;未用DMA技术前&#xff09; &#xff08;2&#xff09;什么是DMA 技术 (Direct Memory Access&#xff09; 直接内存访问&#xff0c;直接内存访问是计算机科学中的一种内存访问技术。…...

给你的边框加点渐变

目录前言border-imageborder-image实现background父子divbackgorund一个div一个伪元素background-clip&#x1f9e8;&#x1f9e8;&#x1f9e8; 大家好&#xff0c;我是搞前端的半夏 &#x1f9d1;&#xff0c;一个热爱写文的前端工程师 &#x1f4bb;. 如果喜欢我的文章&…...

【目标检测】如何使用Yolov8

如何使用Yolov8一、前言二、用法2.1 安装2.2 使用方法2.3 模型2.3.1 目标检测2.3.2 实例分割2.3.3 分类一、前言 一种易于使用的新的对象检测模型。 由 Ultralytics 开发的 Ultralytics YOLOv8 是一种尖端的、最先进的 (SOTA) 模型&#xff1a; https://github.com/ultralyt…...

NVM安装、配置环境、简单使用

nvm 是Node.js 的版本管理工具&#xff0c;可以在同一台电脑上安装多个Node.js版本灵活切换。 安装# sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash 其中0.39.0可以替换为当前最新的版本号。 配置环境变量# cd ~touch .bash_profile…...

【SPSS】数据预处理基础教程(附案例实战)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…...

某饿了么APP最新版逆向分析(二):加密参数初探

二、分析加密参数 说做就做&#xff0c;这边用的python进行模拟请求 万事俱备只欠东风&#xff0c;点击run 发现报错了 怎么回事&#xff1f; 明明请求的内容和抓包的内容完全一致 怎么没有返回我们想要的数据 报错内容为参数错误 因此我就想可能是请求体有参数加密 我…...

程序的编译与链接(预处理详解)+百度面试笔试题+《高质量C/C++编程指南》笔试题

本篇重点介绍程序的编译与链接过程中的预处理阶段&#xff0c;将详细的介绍在预处理阶段会发生什么&#xff0c;以及讲解有关百度该内容的面试笔试题和源于《高质量C/C编程指南》的笔试题。一.【预处理详解】①预定义符号②#define2.1 #define 定义标识符注意&#xff1a;2.2 #…...

全解析 ESM 模块语法,出去还是进来都由你说了算

模块语法是ES6的一个重要特性&#xff0c;它的出现让JavaScript的模块化编程成为了可能。 在JavaScript中可以直接使用import和export关键字来导入和导出模块&#xff0c;但是这种语法并不是ES6的标准&#xff0c;而是ESM&#xff08;ECMAScript Module&#xff09;模块语法的…...

MATLAB 粒子群算法

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…...

java微信小程序音乐播放器分享系统

随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,音乐播放器小程序被用户普遍使用,为方便用户能够可以随时进行音乐播放器小程序的数据信息管理,特开发了基于音乐播放器小程序…...

VS各版本VC各版本对应关系

Visual Studio 经过多年的发展&#xff0c;有许多版本&#xff0c;经常我们在拿到一份代码时不知道对应的VS版本 这时候可以打开工程目录下的vcproj/vcxproj文件&#xff0c;如下所示 <?xml version"1.0" encoding"utf-8"?> <Project DefaultT…...

如何处理“WLAN没有有效的IP配置”这一问题?

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;暂无 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我最大的…...

ElasticSearch-学习笔记05【SpringDataElasticSearch】

Java后端-学习路线-笔记汇总表【黑马程序员】ElasticSearch-学习笔记01【ElasticSearch基本介绍】【day01】ElasticSearch-学习笔记02【ElasticSearch索引库维护】ElasticSearch-学习笔记03【ElasticSearch集群】ElasticSearch-学习笔记04【Java客户端操作索引库】【day02】Ela…...

【GlobalMapper精品教程】045:空间操作(2)——相交(Intersect)

GlobalMapper提供的空间分析(操作)的方法有:交集、并集、单并集、差异、对称差集、相交、重叠、接触、包含、等于、内部、分离等,本文主要讲述相交工具的使用。 文章目录 一、实验数据二、符号化设置三、相交运算四、结果展示五、心灵感悟一、实验数据 加载配套实验数据(…...

Android 一体机研发之修改系统设置————自动锁屏

Android 一体机研发之修改系统设置————屏幕亮度 Android 一体机研发之修改系统设置————声音 Android 一体机研发之修改系统设置————自动锁屏 修改系统设置系列篇章马上开张了&#xff01; 本章将为大家细节讲解自动锁屏。 自动锁屏功能&#xff0c;这个可以根据…...

七天实现一个go rpc框架

目录rpc协议目的关于RPC和框架服务端与消息编码确保接口的实现消息的序列化与反序列化通信过程服务端的实现main 函数支持并发与异步的客户端Call 的设计实现客户端服务注册(service register)通过反射实现 service集成到服务端超时处理创建连接超时Client.Call 超时服务端处理…...

EMQX Cloud Serverless 正式上线:三秒部署、按量计费的 MQTT Serverless 云服务

近日&#xff0c;全球领先的开源物联网数据基础设施软件供应商 EMQ 正式发布了 MQTT Serverless 云服务 —— EMQX Cloud Serverless 的 Beta 版本&#xff0c;开创性地采用弹性多租户技术&#xff0c;用户无需关心服务器基础设施和服务规格伸缩所需资源&#xff0c;仅用三秒即…...

快速排序 容易理解的版本

package huaweiod.排序算法;import java.util.Arrays;public class 快速排序 {public static void main(String[] args) {int[] arr {9,8,3,5,6,7,8,9};mysort(arr, 0, arr.length - 1); // myprint(arr," ");}private static void myprint(int[] arr, Strin…...

Linux体系结构

Linux体系结构一、引入概念二、内核三、管理1、内存管理2、进程管理3、进程调度控制进程对CPU的访问4、设备驱动程序和网络接口四、Linux Shell五、磁盘分区硬盘内的分区Linux下磁盘分区和目录的关系一、引入 操作系统的本质是什么&#xff1f; 是一种管理(协调)资源机制&…...

【汽车电子】什么是ADAS?

文章目录ADAS——先进驾驶辅助系统ADAS——商用车安全性能提升的利器总结ADAS——先进驾驶辅助系统 ADAS&#xff0c;全称Advanced Driver Assistance Systems &#xff0c;“先进驾驶辅助系统”&#xff0c;adas是汽车上面的一种系统&#xff0c;中文名叫做高级驾驶辅助系统&…...

java: 错误: 不支持发行版本 5(快速解决办法)

目录 前言 一、出现报错 二、报错的原因 三、解决办法 四、解决成功 前言 在maven web项目上面要部署运行tomcat时候&#xff0c;会出现这个问题 一、出现报错 java: 错误: 不支持发行版本 5 二、报错的原因 &#xff08;1&#xff09;官方解释&#xff1a;这个错误…...

QT中pro文件常用qmake语法

变量 配置QT模块 QT core gui sql network QT - sql注释 # 开启注释 # DEFINES QT_DISABLE_DEPRECATED_BEFORE0x060000 # disables all the APIs deprecated before Qt 6.0.0添加源文件 SOURCES \main.cpp \widget.cppSOURCES *.cpp SOURCES 1.cpp 2.cpp 3.cpp添加…...

Android 一体机研发之修改系统设置————声音

Android 一体机研发之修改系统设置————屏幕亮度 Android 一体机研发之修改系统设置————声音 Android 一体机研发之修改系统设置————自动锁屏 修改系统设置系列篇章马上开张了&#xff01; 本章将为大家细节讲解声音。 对于声音功能大家都不陌生&#xff0c;在多…...

挖掘长尾关键词的五大思路

本文重点介绍做SEO挖掘长尾词的五大思路&#xff1a;长尾词是搜索量不大&#xff0c;但是关键词的量非常庞大的词&#xff0c;那我们可以通过以下方法挖掘&#xff1a;1、目标型长尾搜索的关键词是直接包含了商业需求的&#xff0c;直接能跟我们的服务或产品对接的&#xff0c;…...

ccc-Brief Introduction of Deep Learning-李宏毅(6)

文章目录Three Steps for Deep LearningFully Connect Feedforward NetworkMatrix OperationOutput Layer as Multi-Class ClassifierExample ApplicationNeural NetworkGoodness of functionPick the best functionThree Steps for Deep Learning 与机器学习三步骤基本相同。 …...

【TVM 学习资料】用 Schedule 模板和 AutoTVM 优化算子

完整 TVM 中文文档&#xff0c;访问→TVM 中文站 作者&#xff1a;Lianmin Zheng&#xff0c;Chris Hoge 本教程将展示如何用 TVM 张量表达式&#xff08;TE&#xff09;语言编写 schedule 模板&#xff0c;并通过 AutoTVM 对模板进行搜索&#xff0c;从而找到最佳 schedule。…...

蓝牙Mesh学习笔记(一)

Mesh系统结构1 Mesh网络分层1.1 模型层(Model layer)1.2 基础模型层(Foundation Model layer)1.3 接入层(Access layer)1.4 上层传输层(Upper transport layer)1.5 下层传输层(Lower transport layer)1.6 网络层(Network layer)1.7 承载层(Bearer layer)1.8 BLE内核规范(BLE Co…...

【1234. 替换子串得到平衡字符串】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 有一个只含有 Q, W, E, R 四种字符&#xff0c;且长度为 n 的字符串。 假如在该字符串中&#xff0c;这四个字符都恰好出现 n/4 次&#xff0c;那么它就是一个「平衡字符串」。 给你一个这样的字符…...

独自开:提供创业机会、享受平台分红、推出新颖赚钱副业

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 前言 独自开&#xff1a;一款聚焦软件定制开发&#xff0c;独立、自主、开放平台 独创分层标准化平台架构,满足系统不断生长的个性化需求多端一键部署前端业务交互与展…...

C++【二叉树进阶(二叉搜索树)】

文章目录前言1、二叉搜索树1-1、 二叉搜索树概念2、二叉搜索树操作2-1、树和节点的基本框架2-2、二叉搜索树的查找2-3、中序遍历2-4、二叉搜索树的插入2-5、二叉搜索树的删除3、二叉搜索树的模拟实现3-1、循环版本3-2、递归版本4、二叉搜索树的应用4-1、K模型4-2、KV模型4-3、K…...

网站根目录 设置/首页关键词优化价格

分享一个大牛的人工智能教程。零基础&#xff01;通俗易懂&#xff01;风趣幽默&#xff01;希望你也加入到人工智能的队伍中来&#xff01;请点击http://www.captainbed.net 两个对象&#xff0c;一个是静态区的“xyz”&#xff0c;一个是用new创建在堆上的对象。...

树莓派wordpress速度如何/google广告投放

2019年中国振动测试设备市场规模达到了XX亿元&#xff0c;预计2026年可以达到XX亿元&#xff0c;未来几年年复合增长率(CAGR)为XX%。本报告研究中国市场振动测试设备的生产、消费及进出口情况&#xff0c;重点关注在中国市场扮演重要角色的全球及本土振动测试设备生产商&#x…...

wordpress+获得子类id/2023新闻大事件摘抄

有人说改系统配置文件&#xff0c;虽说对geek们没啥&#xff0c;但是有一个更方便的方法&#xff0c;更好记。只需记住一个软件&#xff1a; GNOME Color Chooser。 安装完这个软件之后&#xff0c;选择Specific标签&#xff0c;更改Tooltips中的前景色&#xff08;字体颜色&…...

nas wordpress 外网访问/品牌推广的步骤和技巧

阿里巴巴实时计算部-昆仑 最近在学习Flink的Fault Tolerance&#xff0c;了解到Flink在Chandy Lamport Algorithm的基础上扩展实现了一套分布式Checkpointing机制&#xff0c;这个机制在论文"Lightweight Asynchronous Snapshots for Distributed Dataflows"中进行了…...

市场营销一般在哪上班/安卓优化大师官方版

命令简介&#xff1a;该命令用来列出目前与过去登录系统的用户相关信息。指令所在路径&#xff1a;/usr/bin/last 执行last指令时&#xff0c;它会读取位于/var/log目录下名称为wtmp的文件&#xff0c;并把该给文件的内容记录的登录系统的用户名单全部显示出来。默认是显示wtmp…...

搭设企业网站教程/东莞哪种网站推广好

让我们来尝试一次深度匹配&#xff0c;在我们的模式匹配中检查对象的内容。//code-examples/Rounding/match-deep-script.scalacase class Person(name: String, age:Int) val alice new Person("Alice",25) val bob new Person("Bob",32) val charli…...