Linux TUN设备实现Tunnel性能分析

一、TUN/TAP设备原理:

Linux的TUN/TAP设备是一种可以使得应用层与TCP/IP协议栈交互的驱动模块,通常用于组建虚拟局域网中的点对点隧道(Tunnel),可以工作于2层(TAP设备)和3层(TUN设备)数据交换。其工作原理图如下:

1. 数据发送流程

  1. 应用程序通过socket向192.168.1.22地址发送数据{DATA}

  2. 数据进入内核协议栈,协议栈构造IP报文,生成{IP{DATA}}数据,并且分发到虚拟网卡

  3. 虚拟网卡将数据{IP{DATA}}转发到TUN驱动

  4. TUN App从TUN驱动读取到{IP{DATA}}数据,

  5. TUN App通过物理socket发送数据到内核协议栈,

  6. 内核协议栈对数据进行IP报文封装{IP{IP{DATA}}},传送到物理网卡

  7. 数据经过物理网卡送出MAC帧报文{MAC{IP{IP{DATA}}}}

上述流程中:

  • 1为socket write操作(用户空间到内核空间的数据交换)

  • 2,3均为内核数据交换

  • 4为fd read操作(内核空间到用户空间数据交换)

  • 5为socket write操作(用户空间到内核空间数据交换)

  • 6,7均为内核数据交换

2. 数据接收流程

  1. 物理网卡收取到来自网络的MAC帧报文数据包{MAC{IP{IP{DATA}}}},解包

  2. 数据包{IP{IP{DATA}}}进入内核协议栈,进行IP层解包生成{IP{DATA}}数据

  3. 根据数据包地址,数据被分配到TUN App的物理socket

  4. TUN App从socket读出数据{IP{DATA}},然后写入TUN 驱动

  5. TUN 驱动根据写入的IP包目标地址将地址送入对应的虚拟网卡

  6. 虚拟网卡将{IP{DATA}}送入内核协议栈

  7. 协议栈解包成{DATA}送到应用程序的socket

上述流程中:

  • 1,2均为内核数据交换

  • 3为socket read操作(内核空间到用户空间数据交换)

  • 4为fd write操作(用户空间到内核空间数据交换)

  • 5,6均为内核数据交换

  • 7为socket read操作(内核空间到用户空间数据交换)

为了对比,下图显示了直连情况下网络数据的收发流程:

3. 性能损耗点

对比直连网络,通过TUN隧道实现的数据流程中,发送流程中多出了一次TUN fd的读+一次socket写,接收流程中多出了一次socket的读+一次TUN fd的写,这些操作均由运行于用户态的TUN App完成,并且均涉及到用户态到内核态的数据交换,所以性能相比直连网络来说一定会有损耗。我们需要通过一定的测试方法来量化TUN隧道网络的性能跟直连网络的差距,并且找到瓶颈所在,然后提出可行的优化方法。

二、性能测试方法:

  1. 实现一个底层通过UDP建立隧道的TUN Proxy App(分别采用epoll和select模型实现)

  2. 在在两台机器上部署TUN Proxy App,组成VLAN

  3. 使用SCP程序在两台主机之间通过物理连接进行文件copy操作,记录传输性能参数

  4. 使用SCP程序在两台主机之间通过TUN隧道进行文件copy操作,记录传输性能参数

  5. 对比使用物理直连网络和TUN隧道网络传输的性能差异

采用epoll模型的TUN Proxy App的核心逻辑如下:

void packet_switch_epoll::process() {
  logi() << "+++++ process worker is running...";

  if (!evt_.open()) {
    loge() << "failed to open evtio";
    return;
  }

  evtio::evt_context tun_ctx_(fd_tun_, nullptr);
  evtio::evt_context udp_ctx(fd_socket_, nullptr);
  if (!evt_.attach(&tun_ctx_, evtio::op_read)) {
    loge() << "failed to add tun fd to evtio";
    return;
  }

  if (!evt_.attach(&udp_ctx, evtio::op_read)) {
    evt_.detach(&tun_ctx_);
    loge() << "failed to add udp fd to evtio";
    return;
  }

  exit_ = false;

  std::array<uint8_t, 16 * 1024> buf;
  evtio::evt_event_list events;
  while (!exit_) {
    bool ok = evt_.wait(events, 2, -1);
    if (!ok) {
      logw() << "failed to wait";
    }

    for (auto e : events) {
      if (e.context->handle == fd_tun_) {
        forward_with_rw(buf.data(), buf.size(), fd_tun_, fd_socket_);
      } else if (e.context->handle == fd_socket_) {
        forward_with_rw(buf.data(), buf.size(), fd_socket_, fd_tun_);
      } else {
        loge() << "unknown event";
      }
    }
  }

  evt_.close();

  logi() << "----- process worker is exiting...";
}

三、测试结果:

1. scp通过局域网直连,传输10次结果如下:

sample.txt 100%  512MB  47.9MB/s   00:10   
sample.txt 100%  512MB  50.7MB/s   00:10   
sample.txt 100%  512MB  51.6MB/s   00:09   
sample.txt 100%  512MB  49.1MB/s   00:10   
sample.txt 100%  512MB  52.6MB/s   00:09   
sample.txt 100%  512MB  52.4MB/s   00:09   
sample.txt 100%  512MB  51.9MB/s   00:09   
sample.txt 100%  512MB  49.7MB/s   00:10   
sample.txt 100%  512MB  52.0MB/s   00:09   
sample.txt 100%  512MB  50.0MB/s   00:10 

2. scp通过vnet-agent(epoll实现),传输10次结果如下:

sample.txt 100%  512MB  27.3MB/s   00:18   
sample.txt 100%  512MB  28.2MB/s   00:18   
sample.txt 100%  512MB  26.9MB/s   00:19   
sample.txt 100%  512MB  26.8MB/s   00:19   
sample.txt 100%  512MB  25.4MB/s   00:20   
sample.txt 100%  512MB  24.1MB/s   00:21   
sample.txt 100%  512MB  27.8MB/s   00:18   
sample.txt 100%  512MB  23.6MB/s   00:21   
sample.txt 100%  512MB  27.0MB/s   00:18   
sample.txt 100%  512MB  27.5MB/s   00:18    

3. scp通过vnet-agent(select实现),传输10次结果如下:

sample.txt  512MB  19.0MB/s   00:26   
sample.txt  512MB  23.4MB/s   00:21   
sample.txt  512MB  24.4MB/s   00:20   
sample.txt  512MB  24.7MB/s   00:20   
sample.txt  512MB  24.5MB/s   00:20   
sample.txt  512MB  26.4MB/s   00:19   
sample.txt  512MB  26.3MB/s   00:19   
sample.txt  512MB  26.3MB/s   00:19   
sample.txt  512MB  24.2MB/s   00:21   
sample.txt  512MB  26.6MB/s   00:19 

4. 综合对比

结论:

1. 通过TUN隧道会导致网络传输性能损耗超过50%,

2. TUN Proxy App由于只管理有限的socket数量,所以采用select和epoll模型并没有太大性能差异

四、瓶颈分析:

TUN设备驱动内核层的数据交换损耗相对网络IO和用户态和内核态的数据交换来说可以忽略,所以加入TUN隧道代理之后,整体网络性能损耗都是由于运行于应从层的TUN Proxy App引入的。

TUN Proxy App的主要工作为在TUN设备fd和物理连接socket之间进行数据转移:

  • 从TUN设备fd读取要发送的数据到用户空间,然后写入物理连接socket(内核空间)

  • 从物理连接socket读取要收取的数据到用户空间,然后写入TUN设备fd(内核空间)

可以看到以上性能损耗主要存在于数据在用户态和内核态之间的交换。

通过Profiler工具采集scp的发送端的TUN Proxy App分析可以验证如下结果:

耗时主要集中在转发数据的函数中:

int forward_with_rw(uint8_t* buf, int size, int in_fd, int out_fd) {
  // paratmers
  int rlen = 0;
  int wlen = 0;
  int left = 0;
  int offset = 0;

  // read data from source
  rlen = ::read(in_fd, buf, size);
  if (rlen <= 0) {
    loge() << "failed to read data from in fd:" << strerror(errno);
    return -1;
  }

  logv() << "<<<< read " << rlen << " bytes from in fd";

  // write all source data to destination
  left = rlen;
  offset = 0;
  while (left) {
    wlen = ::write(out_fd, buf + offset, left);
    if (wlen <= 0) {
      loge() << "failed to write data to out fd:" << strerror(errno);
      return (rlen - left);
    }
    logv() << ">>>> write " << wlen << " bytes to out fd";

    offset += wlen;
    left -= wlen;
  }

  return wlen;
}

五、解决方案:

TUN Proxy App的性能问题主要是由于在两个fd之间进行数据转移时候产生了两次跨用户/内核态的数据copy,优化方向就是使用更高效的方法来实现在不同fd之间进行zero-copy的数据转移。

1. Linux系统提供了以下技术来实现不同fd之间高效的数据转移方式:

1.sendfile

ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)

sendfile可以直接在内核完成把文件内指定range的数据转移到目标fd内,无需在内核态和用户态之间进行切换。该技术的限制是out_fd必须为一个支持类似mmap功能的文件描述符,socket和tun fd均无法支持,所以此技术不适用。

2.splice

ssize_t splice(int fd_in, off64_t *off_in, 

               int fd_out, off64_t *off_out, 

               size_t len, unsigned int flags);

splice可以利用一个中间pipe实现把数据在fd_in和fd_out之间进行转移,数据操作均发生在内核态,无需切换。实现代码如下:

int forward_with_splice(int in_fd, int out_fd, int pipe[2]) {
  int rc = 0;
  // move data from in fd to pipe
  rc = splice(in_fd, nullptr, pipe[1], nullptr, 4096, SPLICE_F_MOVE | SPLICE_F_MOVE);
  if (rc <= 0) {
    loge() << "failed to move data from in fd to pipe:" << strerror(errno);
    return -1;
  }

  // move data from pipe to out fd
  rc = splice(pipe[0], nullptr, out_fd, nullptr, rc, SPLICE_F_MOVE | SPLICE_F_MOVE);
  if (rc <= 0) {
    loge() << "failed to move data to pipe to out fd" << strerror(errno);
    return -1;
  }

  return rc;
}

splice的要求是fd_in或者fd_out之一必须为pipe,而另一个fd的内核实现中必须支持splice_read, splice_write, sendpage三个文件操作,但是tun fd并没有实现这三个操作,所以目前slice无法支持splice操作。

tun驱动模块源码(linux/drivers/net/tun.c)


static const struct file_operations tun_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read_iter  = tun_chr_read_iter,
.write_iter = tun_chr_write_iter,
.poll = tun_chr_poll,
.unlocked_ioctl = tun_chr_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = tun_chr_compat_ioctl,
#endif
.open = tun_chr_open,
.release = tun_chr_close,
.fasync = tun_chr_fasync,
#ifdef CONFIG_PROC_FS
.show_fdinfo = tun_chr_show_fdinfo,
#endif
};

2. 可行方案

由于TUN模块开发的时候linux还没有splice技术,所以直到如今,都没有开发者来支持该功能,为了优化TUN模块的性能,我们可以选择为TUN模块实现此功能,实现之后的应用方式可以有两种

  1. 直接修改tun.c然后,提供一个支持splice技术的tun模块

  2. 保持tun模块现有能力,基于tun.c实现一个新的私有模块并且支持splice,可以于现有tun共存于内核中

以上两种方式稳定之后均可以向linux内核提交patch。

支持splice操作之后,保守估计TUN隧道网络的性能至少能达到直连网络的90%。

六、补充测试数据

===================== Test UDP-Direct bandwidth =====================

Connecting to host 172.16.203.128, port 5201

[  5] local 172.16.203.129 port 36058 connected to 172.16.203.128 port 5201

[ ID] Interval           Transfer     Bitrate         Total Datagrams

[  5]   0.00-1.00   sec  53.3 MBytes  53.3 MBytes/sec  38602  

[  5]   1.00-2.00   sec  54.6 MBytes  54.6 MBytes/sec  39569  

[  5]   2.00-3.00   sec  54.9 MBytes  54.9 MBytes/sec  39761  

[  5]   3.00-4.00   sec  54.8 MBytes  54.8 MBytes/sec  39712  

[  5]   4.00-5.00   sec  54.8 MBytes  54.8 MBytes/sec  39712  

[  5]   5.00-6.00   sec  55.0 MBytes  55.0 MBytes/sec  39825  

[  5]   6.00-7.00   sec  55.5 MBytes  55.5 MBytes/sec  40203  

[  5]   7.00-8.00   sec  55.4 MBytes  55.4 MBytes/sec  40134  

[  5]   8.00-9.00   sec  55.5 MBytes  55.5 MBytes/sec  40196  

[  5]   9.00-10.00  sec  55.7 MBytes  55.6 MBytes/sec  40300  

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval       Transfer   Bitrate         Jitter    Lost/Total Datagrams

[  5] 0.00-10.00 sec 550 MBytes  55.0 MBytes/sec  0.000 ms  0/398014 (0%)  sender

[  5] 0.00-9.98  sec 513 MBytes  51.4 MBytes/sec  0.014 ms  26226/398014 (6.6%)  receiver

 

iperf Done.

===================== Test UDP-over-TUN bandwidth =====================

Connecting to host 10.0.0.11, port 5201

[  5] local 10.0.0.22 port 43678 connected to 10.0.0.11 port 5201

[ ID] Interval           Transfer     Bitrate         Total Datagrams

[  5]   0.00-1.00   sec  78.1 MBytes  78.1 MBytes/sec  56524  

[  5]   1.00-2.00   sec  78.5 MBytes  78.5 MBytes/sec  56867  

[  5]   2.00-3.00   sec  78.8 MBytes  78.8 MBytes/sec  57060  

[  5]   3.00-4.00   sec  78.9 MBytes  78.9 MBytes/sec  57137  

[  5]   4.00-5.00   sec  78.7 MBytes  78.7 MBytes/sec  56962  

[  5]   5.00-6.00   sec  79.1 MBytes  79.1 MBytes/sec  57305  

[  5]   6.00-7.00   sec  79.0 MBytes  79.0 MBytes/sec  57197  

[  5]   7.00-8.00   sec  78.5 MBytes  78.5 MBytes/sec  56823  

[  5]   8.00-9.00   sec  78.7 MBytes  78.7 MBytes/sec  57017  

[  5]   9.00-10.00  sec  78.5 MBytes  78.5 MBytes/sec  56816  

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval       Transfer     Bitrate         Jitter    Lost/Total Datagrams

[  5] 0.00-10.00 sec 787 MBytes  78.7 MBytes/sec  0.000 ms  0/569708 (0%)  sender

[  5] 0.00-10.19 sec 228 MBytes  22.4 MBytes/sec  0.180 ms  404614/569704 (71%)  receiver

 

iperf Done.

===================== Test TCP-Direct bandwidth =====================

Connecting to host 172.16.203.128, port 5201

[  5] local 172.16.203.129 port 40554 connected to 172.16.203.128 port 5201

[ ID] Interval           Transfer     Bitrate         Retr  Cwnd

[  5]   0.00-1.00   sec  48.3 MBytes  48.3 MBytes/sec    0   2.31 MBytes       

[  5]   1.00-2.00   sec  29.6 MBytes  29.6 MBytes/sec    0   2.70 MBytes       

[  5]   2.00-3.00   sec  31.0 MBytes  31.0 MBytes/sec    0   2.70 MBytes       

[  5]   3.00-4.00   sec  31.4 MBytes  31.4 MBytes/sec    0   2.70 MBytes       

[  5]   4.00-5.00   sec  31.0 MBytes  31.0 MBytes/sec    0   2.70 MBytes       

[  5]   5.00-6.00   sec  31.1 MBytes  31.1 MBytes/sec    0   2.70 MBytes       

[  5]   6.00-7.00   sec  31.8 MBytes  31.8 MBytes/sec    0   2.70 MBytes       

[  5]   7.00-8.00   sec  31.0 MBytes  31.0 MBytes/sec    0   2.70 MBytes       

[  5]   8.00-9.00   sec  31.8 MBytes  31.7 MBytes/sec    0   2.70 MBytes       

[  5]   9.00-10.00  sec  31.5 MBytes  31.5 MBytes/sec    0   2.70 MBytes       

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval           Transfer     Bitrate         Retr

[  5]   0.00-10.00  sec   328 MBytes  32.8 MBytes/sec    0             sender

[  5]   0.00-10.04  sec   328 MBytes  32.7 MBytes/sec                  receiver

 

iperf Done.

===================== Test TCP-over-TUN bandwidth =====================

Connecting to host 10.0.0.11, port 5201

[  5] local 10.0.0.22 port 32876 connected to 10.0.0.11 port 5201

[ ID] Interval           Transfer     Bitrate         Retr  Cwnd

[  5]   0.00-1.00   sec  19.6 MBytes  19.6 MBytes/sec  152    127 KBytes       

[  5]   1.00-2.00   sec  20.4 MBytes  20.4 MBytes/sec    0    218 KBytes       

[  5]   2.00-3.00   sec  18.8 MBytes  18.8 MBytes/sec   68    147 KBytes       

[  5]   3.00-4.00   sec  20.1 MBytes  20.1 MBytes/sec    0    229 KBytes       

[  5]   4.00-5.00   sec  20.4 MBytes  20.4 MBytes/sec    1    233 KBytes       

[  5]   5.00-6.00   sec  19.8 MBytes  19.8 MBytes/sec   70    158 KBytes       

[  5]   6.00-7.00   sec  19.6 MBytes  19.6 MBytes/sec   47    140 KBytes       

[  5]   7.00-8.00   sec  20.0 MBytes  20.0 MBytes/sec   23    148 KBytes       

[  5]   8.00-9.00   sec  18.6 MBytes  18.6 MBytes/sec    8    150 KBytes       

[  5]   9.00-10.00  sec  19.6 MBytes  19.6 MBytes/sec   19    189 KBytes       

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval           Transfer     Bitrate         Retr

[  5]   0.00-10.00  sec   197 MBytes  19.7 MBytes/sec  388             sender

[  5]   0.00-9.99   sec   195 MBytes  19.5 MBytes/sec                  receiver

 

iperf Done.

七、应用层读写操作API与TUN FD的兼容性

支持

read/write

✅ 

readv/writev

✅ 

recv/send

❌ 

ENOTSOCK(88)Socket operation on non-socket

recvmsg/sendmsg

❌ 

ENOTSOCK(88)Socket operation on non-socket

recvmmsg/sendmmsg

❌ 

ENOTSOCK(88)Socket operation on non-socket


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/514112.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【环境变量】命令行参数 | 概念 | 理解 | 命令行参数表 | bash进程

目录 四组概念 命令行参数概念&理解 查看命令函参数 命令行字符串&命令行参数表 命令行参数存在的意义 谁形成的命令行参数 父进程&子进程&数据段 bash进程 最近有点小忙&#xff0c;可能更新比较慢。 四组概念 竞争性: 系统进程数目众多&#xff0c…

了解这些技术:Flutter应用顺利登陆iOS平台的步骤与方法

引言 &#x1f680; Flutter作为一种跨平台的移动应用程序开发框架&#xff0c;为开发者提供了便利&#xff0c;使他们能够通过单一的代码库构建出高性能、高保真度的应用程序&#xff0c;同时支持Android和iOS两个平台。然而&#xff0c;完成Flutter应用程序的开发只是第一步…

【WebKit架构讲解】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

Apache ECharts-数据统计(详解、入门案例)

简介&#xff1a;Apache ECharts 是一款基于 Javascript 的数据可视化图表库&#xff0c;提供直观&#xff0c;生动&#xff0c;可交互&#xff0c;可个性化定制的数据可视化图表。 1、介绍 图 1.1 Apache ECharts 功能、运行环境 功能&#xff1a; ECharts&#xff…

[C#]winform使用OpenCvSharp实现透视变换功能支持自定义选位置和删除位置

【透视变换基本原理】 OpenCvSharp 是一个.NET环境下对OpenCV原生库的封装&#xff0c;它提供了大量的计算机视觉和图像处理的功能。要使用OpenCvSharp实现透视变换&#xff08;Perspective Transformation&#xff09;&#xff0c;你首先需要理解透视变换的原理和它在图像处理…

巨控GRM560无线5G远程模块MQTT网关物联网盒子PLC远程监控制调试

巨控科技依靠数十年在工业物联网方面的技术沉淀&#xff0c;历时3年研发&#xff0c;于2024年正式发布新一代巨控产品。本次发布包含5G PLC无线通讯模块GRM560系列&#xff0c;OPC无线通讯模块OPC560系列&#xff0c;高性能PLC协议转换网关NET400系列。 选型技术支持&#xff1…

如何防止IP泄露,安全匿名上网?

当互联网成为每个家庭的重要组成部分后&#xff0c;IP地址就成了你的虚拟地址。您的请求从该地址开始&#xff0c;然后 Internet 将消息发送回该地址。那么&#xff0c;您担心您的地址被泄露吗&#xff1f; 对于安全意识高或者某些业务需求的用户&#xff0c;如果您正在寻找保护…

大模型学习笔记八:手撕AutoGPT

文章目录 一、功能需求二、演示用例三、核心模块流程图四、代码分析1&#xff09;Agent类目录创建智能体对象2&#xff09;开始主流程3&#xff09;在prompt的main目录输入主prompt和最后prompt4&#xff09;增加实际的工具集tools&#xff08;也就是函数&#xff09;5&#xf…

20240403在ubuntu20.04下解压缩gz压缩包

20240403在ubuntu20.04下解压缩gz压缩包.txt 2024/4/3 15:17 缘起&#xff1a;使用友善之臂FriendlyElec的NanoPi NEO Core开发板 https://wiki.friendlyelec.com/wiki/index.php/NanoPi_NEO/zh#.E8.BF.90.E8.A1.8CFriendlyCore NanoPi NEO/zh http://wiki.friendlyelec.com/w…

【ArduinoQuartus】在小脚丫STEP CYC10上安装PulseRain Reindeer并在软核上运行基础功能

【Arduino&Quartus】在小脚丫STEP CYC10上安装PulseRain Reindeer并在软核上运行基础功能 一、将Reindeer软核下载到STEP CYC10&#xff08;一&#xff09;下载PulseRain Reindeer软核&#xff08;二&#xff09;配置Reindeer软核到开发板1.将sof文件转换为jic文件2.将jic文…

【opencv】教程代码 —Histograms_Matching(1)反向投影:在给定图像中寻找特定的颜色或颜色分布...

1. calcBackProject_Demo1.cpp 反向投影函数的使用 /*** file BackProject_Demo1.cpp* brief 示例代码&#xff0c;演示反向投影函数的使用* author OpenCV团队*/#include "opencv2/imgproc.hpp" // 包括图像处理相关功能的头文件 #include "opencv2/imgcodecs…

蓝奏云直链获取在线解析网站源码

源码简介 蓝奏云直链获取在线解析网站源码 蓝奏云链接解析 本地API接口 支持有无密码和短期直链和永久直链&#xff0c;同时还可以显示文件名和大小。 这个解析器无需数据库即可搭建&#xff0c;API接口已经本地化&#xff0c;非常简单易用。 安装环境 php5.6 搭建教程 …

构建第一个JS应用(FA模型)

创建JS工程 若首次打开DevEco Studio&#xff0c;请点击Create Project创建工程。如果已经打开了一个工程&#xff0c;请在菜单栏选择File > New > Create Project来创建一个新工程。选择Application应用开发&#xff08;本文以应用开发为例&#xff0c;Atomic Service对…

4.6 offset指令,jmp short指令,far,dword ptr各种跳转指令

4.6 offset指令&#xff0c;jmp short指令&#xff0c;far&#xff0c;dword ptr各种跳转指令 可以修改IP&#xff0c;或同时修改CS和IP的指令统称为转移指令。概括的讲&#xff0c;转移指令就是可以控制CPU执行内存中某处代码的指令 1. 转移指令 1.1 8086CPU的转移行为有以…

《PDVC》论文笔记

PS&#xff1a;模型代码解释清明后出 原文链接&#xff1a; [2108.07781v1] End-to-End Dense Video Captioning with Parallel Decoding (arxiv.org) 原文笔记&#xff1a; What&#xff1a; End-to-End Dense Video Captioning with Parallel Decoding 并行解码的端到端…

DDL ---- 数据库的操作

1.查询所有数据库 show databases; 上图除了自创的&#xff0c;其他的四个都是mysql自带的数据库 。&#xff08;不区分大小写&#xff09; 2.查询当前数据库 select database(); 最开始没有使用数据库&#xff0c;那么查找结果为NULL 所以我们就需要先使用数据库&#xff…

鸿蒙分布式音乐播放-如何完成播放、暂停、上一曲、下一曲功能

介绍 本示例使用fileIo获取指定音频文件&#xff0c;并通过AudioPlayer完成了音乐的播放完成了基本的音乐播放、暂停、上一曲、下一曲功能&#xff1b;并使用DeviceManager完成了分布式设备列表的显示和分布式能力完成了音乐播放状态的跨设备分享。 本示例用到了与用户进行交…

是德科技keysight 33621A波形发生器

181/2461/8938产品概述&#xff1a; 与上一代DDS波形发生器相比&#xff0c;采用独家Trueform技术的安捷伦HP 33621A波形发生器具有更高的性能、保真度和灵活性。安捷伦HP 33621A 120 MHz、单通道、Trueform arbs&#xff0c;带时序控制和64 MSa存储器&#xff0c;1 ps抖动&am…

数据库管理工具 DBeaverUE for Mac激活版

DBeaverUE for Mac是一款功能强大且易于使用的数据库管理工具&#xff0c;专为Mac用户设计。它支持多种数据库类型&#xff0c;如MySQL、PostgreSQL、Oracle等&#xff0c;使得用户可以轻松管理和操作各种数据库。 软件下载&#xff1a;DBeaverUE for Mac激活版下载 DBeaverUE …

51单片机入门_江协科技_20.1_Proteus串口仿真

1.为了解决51单片机学习过程中在Proteus中的串口仿真的问题&#xff0c;需要在Proteus中建立串口仿真的环境&#xff08;目前Proteus安装在Win7x64虚拟机环境中&#xff1b; 2. 在CSDN中找到VSPD下载地址&#xff0c;在虚拟机中进行VSPD的安装&#xff0c;具体链接地址如下&am…