.Net8顶级技术:边界检查之IR解析(二)

news2024/11/26 1:24:29

前言

IR技术应用在各个编程语言当中,它属于JIT的核心部分,确实有点点麻烦。但部分基本明了。本篇通过.Net8里面的边界检查的小例子了解下。前情提要,看这一篇之前建议看看前一篇:点击此处,以便于理解。

概括

1.前奏
先上C#代码:

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool Test(int[] array)
{
   for (int i = 0; i < 0x12345; i++)
   {
      if (array[i] == 42)
      {
         return true;
      }
   }
  return false;
}

Test函数经过Roslyn编译成IL代码之后,会被JIT导入及操作变成IR。

BBnum BBid ref try hnd preds           weight    lp [IL range]     [jump]      [EH region]         [flags]
-----------------------------------------------------------------------------------------------------------------------------------------
BB01 [0007]  1                             1       [???..???)-> BB04 ( cond )                     internal 
BB02 [0001]  2       BB01,BB03             4     0 [004..00B)-> BB05 ( cond )                     i Loop idxlen bwd bwd-target align 
BB03 [0003]  1       BB02                  4     0 [00D..019)-> BB02 ( cond )                     i bwd 
BB04 [0005]  2       BB01,BB03             0.50    [019..01B)        (return)                     i 
BB05 [0002]  1       BB02                  0.50    [00B..00D)        (return)                     i 
-----------------------------------------------------------------------------------------------------------------------------------------

可以看到IL被分割成了五个BB(basic block).注意表格的BBnum和jump列。BB01的BBnum就是BB01,它的jump是BB04。为啥是BB04?因为BB01的IR表示的是如果(i>=0x12345),则跳转到BB04,也就是BB01的正常逻辑。下面看下这个五个BB.

------------ BB01 [???..???) -> BB04 (cond), preds={} succs={BB02,BB04}
***** BB01
STMT00006 ( 0x011[E-] ... ??? )
     (  7,  9) [000038] -----------                         *  JTRUE     void  
     (  5,  7) [000039] J------N---                         \--*  GE        int   
     (  3,  2) [000040] -----------                            +--*  LCL_VAR   int    V01 loc0         
     (  1,  4) [000041] -----------                            \--*  CNS_INT   int    0x12345

------------ BB02 [004..00B) -> BB05 (cond), preds={BB01,BB03} succs={BB03,BB05}
***** BB02
STMT00002 ( 0x004[E-] ... 0x009 )
               [000013] ---XG+-----                         *  JTRUE     void  
               [000012] N--XG+-N-U-                         \--*  EQ        int   
               [000034] ---XG+-----                            +--*  COMMA     int   
               [000026] ---X-+-----                            |  +--*  BOUNDS_CHECK_Rng void  
               [000008] -----+-----                            |  |  +--*  LCL_VAR   int    V01 loc0         
               [000025] ---X-+-----                            |  |  \--*  ARR_LENGTH int   
               [000007] -----+-----                            |  |     \--*  LCL_VAR   ref    V00 arg0         
               [000035] n---G+-----                            |  \--*  IND       int   
               [000033] -----+-----                            |     \--*  ARR_ADDR  byref int[]
               [000032] -----+-----                            |        \--*  ADD       byref 
               [000023] -----+-----                            |           +--*  LCL_VAR   ref    V00 arg0         
               [000031] -----+-----                            |           \--*  ADD       long  
               [000029] -----+-----                            |              +--*  LSH       long  
               [000027] -----+---U-                            |              |  +--*  CAST      long <- uint
               [000024] -----+-----                            |              |  |  \--*  LCL_VAR   int    V01 loc0         
               [000028] -----+-N---                            |              |  \--*  CNS_INT   long   2
               [000030] -----+-----                            |              \--*  CNS_INT   long   16
               [000011] -----+-----                            \--*  CNS_INT   int    42

------------ BB03 [00D..019) -> BB02 (cond), preds={BB02} succs={BB04,BB02}
***** BB03
STMT00003 ( 0x00D[E-] ... 0x010 )
               [000018] -A---+-----                         *  ASG       int   
               [000017] D----+-N---                         +--*  LCL_VAR   int    V01 loc0         
               [000016] -----+-----                         \--*  ADD       int   
               [000014] -----+-----                            +--*  LCL_VAR   int    V01 loc0         
               [000015] -----+-----                            \--*  CNS_INT   int    1

***** BB03
STMT00001 ( 0x011[E-] ... 0x017 )
     (  7,  9) [000006] -----------                         *  JTRUE     void  
     (  5,  7) [000005] J------N---                         \--*  LT        int   
     (  3,  2) [000003] -----------                            +--*  LCL_VAR   int    V01 loc0         
     (  1,  4) [000004] -----------                            \--*  CNS_INT   int    0x12345

------------ BB04 [019..01B) (return), preds={BB01,BB03} succs={}
***** BB04
STMT00005 ( 0x019[E-] ... 0x01A )
               [000022] -----+-----                         *  RETURN    int   
               [000037] -----+-----                         \--*  CNS_INT   int    0

------------ BB05 [00B..00D) (return), preds={BB02} succs={}
***** BB05
STMT00004 ( 0x00B[E-] ... 0x00C )
               [000020] -----+-----                         *  RETURN    int   
               [000036] -----+-----                         \--*  CNS_INT   int    1

preds表示能在逻辑上执行到当前块的所有快,succs表示当前语句逻辑能达到的BB块。举个例子:比如BB01,首先看下这条IR表示的如果(i>=0x12345),则跳转到BB04,也就是直接返回0。因为逻辑是索引大于了循环的最大次数,是不合理的。如果(i<0x12345),则跳转到BB02,也就是判断(array[i]是否等于42)。上面BB01的predes为空,则表示没有逻辑能达到这条语句。它的succs为BB02和BB04,跟上面的推测吻合。其它依次类推。

2.BB的IR表示
通过上面的BB01到BB05的观察,得知它们分别表示如下:
一:BB01

if(i>=0x12345)

二:BB02

if(array[i]==42)

三:BB03

i=i+1;
if(i<0x12345)

四:BB04

return 0

五:BB05

return 1

以上循环被分割成了五个BB。它的实际逻辑如下:

if(i>=0x12345)
{
  return flase;
}
else
{
  for(i<0x12345;i++)
  {
    if(array[i]==42)
    {
      return true;
    }
  }
  return flase;
}

所以呢,实际是示例的for循环,被分解成了上面的代码。但是还没完,为了确保这个array[i]不会出现内存访问的错误,BB02里面有个BOUNDS_CHECK_Rng的边界检查技术,它会判断array[i]里的i索引是否查过array.length的长度,因为在for循环里面,所以每次都会判断,会增加相应的开销。为了达到最优的效果,.Net8会去掉这开销。那么应该怎么做呢?继续看。
JIT先增加BB06,BB07,BB08,BB09四个块,然后把BOUNDS_CHECK_Rng给去掉。
去掉前后对比如下。
去掉前:

[000013] ---XG+-----                         *  JTRUE     void  
               [000012] N--XG+-N-U-                         \--*  EQ        int   
               [000034] ---XG+-----                            +--*  COMMA     int   
               [000026] ---X-+-----                            |  +--*  BOUNDS_CHECK_Rng void  
               [000008] -----+-----                            |  |  +--*  LCL_VAR   int    V01 loc0         
               [000025] ---X-+-----                            |  |  \--*  ARR_LENGTH int   
               [000007] -----+-----                            |  |     \--*  LCL_VAR   ref    V00 arg0         
               [000035] n---G+-----                            |  \--*  IND       int   
               [000033] -----+-----                            |     \--*  ARR_ADDR  byref int[]
               [000032] -----+-----                            |        \--*  ADD       byref 
               [000023] -----+-----                            |           +--*  LCL_VAR   ref    V00 arg0         
               [000031] -----+-----                            |           \--*  ADD       long  
               [000029] -----+-----                            |              +--*  LSH       long  
               [000027] -----+---U-                            |              |  +--*  CAST      long <- uint
               [000024] -----+-----                            |              |  |  \--*  LCL_VAR   int    V01 loc0         
               [000028] -----+-N---                            |              |  \--*  CNS_INT   long   2
               [000030] -----+-----                            |              \--*  CNS_INT   long   16
               [000011] -----+-----                            \--*  CNS_INT   int    42

去掉后:

[000013] ----G+-----                         *  JTRUE     void  
               [000012] N---G+-N-U-                         \--*  EQ        int   
               [000034] ----G+-N---                            +--*  COMMA     int   
               [000026] -----+-----                            |  +--*  NOP       void  
               [000035] n---G+-----                            |  \--*  IND       int   
               [000033] -----+-----                            |     \--*  ARR_ADDR  byref int[]
               [000032] -----+-----                            |        \--*  ADD       byref 
               [000023] -----+-----                            |           +--*  LCL_VAR   ref    V00 arg0         
               [000031] -----+-----                            |           \--*  ADD       long  
               [000029] -----+-----                            |              +--*  LSH       long  
               [000027] -----+---U-                            |              |  +--*  CAST      long <- uint
               [000024] -----+-----                            |              |  |  \--*  LCL_VAR   int    V01 loc0         
               [000028] -----+-N---                            |              |  \--*  CNS_INT   long   2
               [000030] -----+-----                            |              \--*  CNS_INT   long   16
               [000011] -----+-----                            \--*  CNS_INT   int    42

然后再新增BB10,BB11,BB12,BB13四个BB块。这些BB块如下所示:

------------ BB01 [???..???) -> BB12 (cond), preds={} succs={BB02,BB12}

***** BB01
STMT00006 ( 0x011[E-] ... ??? )
     (  7,  9) [000038] -----------                         *  JTRUE     void  
     (  5,  7) [000039] J------N---                         \--*  GE        int   
     (  3,  2) [000040] -----------                            +--*  LCL_VAR   int    V01 loc0         
     (  1,  4) [000041] -----------                            \--*  CNS_INT   int    0x12345

------------ BB02 [???..???), preds={BB01} succs={BB03}

------------ BB03 [???..???) -> BB09 (cond), preds={BB02} succs={BB04,BB09}

***** BB03
STMT00010 ( ??? ... ??? )
     (  7,  6) [000072] -----------                         *  JTRUE     void  
     (  5,  4) [000071] J------N---                         \--*  EQ        int   
     (  3,  2) [000069] -----------                            +--*  LCL_VAR   ref    V00 arg0         
     (  1,  1) [000070] -----------                            \--*  CNS_INT   ref    null

------------ BB04 [???..???) -> BB09 (cond), preds={BB03} succs={BB05,BB09}

***** BB04
STMT00011 ( ??? ... ??? )
     (  7,  6) [000076] -----------                         *  JTRUE     void  
     (  5,  4) [000075] J------N---                         \--*  LT        int   
     (  3,  2) [000073] -----------                            +--*  LCL_VAR   int    V01 loc0         
     (  1,  1) [000074] -----------                            \--*  CNS_INT   int    0

------------ BB05 [???..???) -> BB09 (cond), preds={BB04} succs={BB06,BB09}

***** BB05
STMT00012 ( ??? ... ??? )
     (  9, 11) [000081] ---X-------                         *  JTRUE     void  
     (  7,  9) [000080] J--X---N---                         \--*  LT        int   
     (  5,  4) [000079] ---X-------                            +--*  ARR_LENGTH int   
     (  3,  2) [000078] -----------                            |  \--*  LCL_VAR   ref    V00 arg0         
     (  1,  4) [000077] -----------                            \--*  CNS_INT   int    0x12345

------------ BB06 [004..00B) -> BB13 (cond), preds={BB05,BB07} succs={BB07,BB13}

***** BB06
STMT00002 ( 0x004[E-] ... 0x009 )
               [000013] ----G+-----                         *  JTRUE     void  
               [000012] N---G+-N-U-                         \--*  EQ        int   
               [000034] ----G+-N---                            +--*  COMMA     int   
               [000026] -----+-----                            |  +--*  NOP       void  
               [000035] n---G+-----                            |  \--*  IND       int   
               [000033] -----+-----                            |     \--*  ARR_ADDR  byref int[]
               [000032] -----+-----                            |        \--*  ADD       byref 
               [000023] -----+-----                            |           +--*  LCL_VAR   ref    V00 arg0         
               [000031] -----+-----                            |           \--*  ADD       long  
               [000029] -----+-----                            |              +--*  LSH       long  
               [000027] -----+---U-                            |              |  +--*  CAST      long <- uint
               [000024] -----+-----                            |              |  |  \--*  LCL_VAR   int    V01 loc0         
               [000028] -----+-N---                            |              |  \--*  CNS_INT   long   2
               [000030] -----+-----                            |              \--*  CNS_INT   long   16
               [000011] -----+-----                            \--*  CNS_INT   int    42

------------ BB07 [00D..019) -> BB06 (cond), preds={BB06} succs={BB08,BB06}

***** BB07
STMT00003 ( 0x00D[E-] ... 0x010 )
               [000018] -A---+-----                         *  ASG       int   
               [000017] D----+-N---                         +--*  LCL_VAR   int    V01 loc0         
               [000016] -----+-----                         \--*  ADD       int   
               [000014] -----+-----                            +--*  LCL_VAR   int    V01 loc0         
               [000015] -----+-----                            \--*  CNS_INT   int    1

***** BB07
STMT00001 ( 0x011[E-] ... 0x017 )
     (  7,  9) [000006] -----------                         *  JTRUE     void  
     (  5,  7) [000005] J------N---                         \--*  LT        int   
     (  3,  2) [000003] -----------                            +--*  LCL_VAR   int    V01 loc0         
     (  1,  4) [000004] -----------                            \--*  CNS_INT   int    0x12345

------------ BB08 [???..???) -> BB12 (always), preds={BB07} succs={BB12}

------------ BB09 [???..???), preds={BB03,BB04,BB05} succs={BB10}

------------ BB10 [004..00B) -> BB13 (cond), preds={BB09,BB11} succs={BB11,BB13}

***** BB10
STMT00007 ( 0x004[E-] ... ??? )
               [000042] ---XGO-----                         *  JTRUE     void  
               [000043] N--XGO-N-U-                         \--*  EQ        int   
               [000044] ---XGO-----                            +--*  COMMA     int   
               [000045] ---X-O-----                            |  +--*  BOUNDS_CHECK_Rng void  
               [000046] -----------                            |  |  +--*  LCL_VAR   int    V01 loc0         
               [000047] ---X-------                            |  |  \--*  ARR_LENGTH int   
               [000048] -----------                            |  |     \--*  LCL_VAR   ref    V00 arg0         
               [000049] n---GO-----                            |  \--*  IND       int   
               [000050] -----O-----                            |     \--*  ARR_ADDR  byref int[]
               [000051] -----------                            |        \--*  ADD       byref 
               [000052] -----------                            |           +--*  LCL_VAR   ref    V00 arg0         
               [000053] -----------                            |           \--*  ADD       long  
               [000054] -----------                            |              +--*  LSH       long  
               [000055] ---------U-                            |              |  +--*  CAST      long <- uint
               [000056] -----------                            |              |  |  \--*  LCL_VAR   int    V01 loc0         
               [000057] -------N---                            |              |  \--*  CNS_INT   long   2
               [000058] -----------                            |              \--*  CNS_INT   long   16
               [000059] -----------                            \--*  CNS_INT   int    42

------------ BB11 [00D..019) -> BB10 (cond), preds={BB10} succs={BB12,BB10}

***** BB11
STMT00008 ( 0x00D[E-] ... ??? )
               [000060] -A---------                         *  ASG       int   
               [000061] D------N---                         +--*  LCL_VAR   int    V01 loc0         
               [000062] -----------                         \--*  ADD       int   
               [000063] -----------                            +--*  LCL_VAR   int    V01 loc0         
               [000064] -----------                            \--*  CNS_INT   int    1

***** BB11
STMT00009 ( 0x011[E-] ... ??? )
     (  7,  9) [000065] -----------                         *  JTRUE     void  
     (  5,  7) [000066] J------N---                         \--*  LT        int   
     (  3,  2) [000067] -----------                            +--*  LCL_VAR   int    V01 loc0         
     (  1,  4) [000068] -----------                            \--*  CNS_INT   int    0x12345

------------ BB12 [019..01B) (return), preds={BB01,BB08,BB11} succs={}

***** BB12
STMT00005 ( 0x019[E-] ... 0x01A )
               [000022] -----+-----                         *  RETURN    int   
               [000037] -----+-----                         \--*  CNS_INT   int    0

------------ BB13 [00B..00D) (return), preds={BB06,BB10} succs={}

***** BB13
STMT00004 ( 0x00B[E-] ... 0x00C )
               [000020] -----+-----                         *  RETURN    int   
               [000036] -----+-----                         \--*  CNS_INT   int    1

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

3.BB块分析
通过去掉的边界检查,进行的优化之后。新增了7个BB块,总共有13个BB块。那么这些BB干嘛的呢?实际上就是为了去掉边界检查(因为在for循环里,每次都要判断),而确保内存array[i]在正确内存范围内。逐一来看下:
BB01:

if(i>=0x12345)判断索引是否大于循环最大值

BB02

BB03

if(array==null) //这里是判断数组的地址是否等于0

BB04

if(i<0)判断索引是否小于0

BB05

if(array.length<0x12345)判断数组长度是否小于循环最大数0x12345

BB06

if(array[i]==42)

BB07

i=i+1索引自增

BB08

BB09

BB10

if(i<array.length) //这里跟上面的BB06一样,但是多了边界检查。BB06去掉,这里没去掉。是因为这里需要边界检查,而BB06不需要。一个快速路径,一个慢速路径。
if(array[i]==42)

BB11

i=i+1

BB12

return 0

BB02

return 1

它实际逻辑是:

if(i<0x12345 && array!= null && i>0 && array.Length >= 0x12345 )//再去掉边界检查之后的优化里,这进行大量的检查,确保array[i],在正确内存范围内。
{
    for (int i = 0; i < 0x12345; i++)
    {
        if (array[i] == 42) 不检查边界,因为上面的if检查过了
        {
            return true;
        }
    }
}
else  //如果上面的if有一个条件不符合,则进行边界检查。优化不成功
{
   for (int i = 0; i < 0x12345; i++)
    {
        if (array[i] == 42) 这里需要边界检查也就是BOUNDS_CHECK_Rng
        {
            return true;
        }
    }
}

结尾

作者:江湖评谈
欢迎关注公众号,第一时间首发分享技术文章。image

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

POSTGRESQL PG15关于归档的新模式

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到3群&#xff08;共…

chatgpt赋能python:PythonSoup对于爬虫程序员来说为什么如此重要

Python Soup 对于爬虫程序员来说为什么如此重要 介绍 Python是现代编程世界中最广泛使用的语言之一。它是一个高级编程语言&#xff0c;可用于许多应用程序&#xff0c;从机器学习到游戏开发再到网络爬虫。对于网络爬虫&#xff0c;Python Soup是非常重要的工具之一。Soup是一…

如何像访问百度一样访问家里的服务器?(三)

来源&#xff1a;公众号【鱼鹰谈单片机】 作者&#xff1a;鱼鹰Osprey ID &#xff1a;emOsprey 在前面的两篇笔记《家里宽带搞个服务器&#xff0c;YYDS&#xff08;一&#xff09;》《家里宽带申请公网 IP&#xff08;二&#xff09;》&#xff0c;介绍了如何获取公网 IP&a…

chatgpt赋能python:Python%6简介

Python %6 简介 什么是Python %6&#xff1f; Python %6指的是在Python中使用%6操作符来计算一个数的余数。余数是指在进行整除时所剩余下的数字。在Python中&#xff0c;使用%符号来表示计算余数&#xff0c;因此%6表示计算一个数除以6所剩下的余数。 为什么要使用Python %…

Golang每日一练(leetDay0076) 第k大元素、组合总和III

目录 215. 数组中的第K个最大元素 Kth-largest-element-in-an-array &#x1f31f;&#x1f31f; 216. 组合总和 III Combination Sum iii &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日…

13 Binder通信之ServiceManager

Binder通信之ServiceManager 一、前言 Android系统中存在很多service,当某个应用调用系统某个service的功能时,往往向系统发出请求,调用该服务的外部接口,这种外部接口我们通常叫做代理接口,也就是说要拿到目标服务需要先拿到目标服务的代理。这个时候,如果每个应用cli…

少林派问题汇总2

Q&#xff1a; torch转bmodel模型时&#xff0c;bmnetp工具报错 A&#xff1a; 有的模型涉及到动态shape&#xff0c;需要设置成动态编译dyntrue Q&#xff1a; A&#xff1a; 内存占满了&#xff0c;进程被系统kill掉了&#xff0c;运行内存建议12g以上 Q&#xff1a; ss…

企业级API网关之典型应用场景

目 录 01 企业面对API与网关的现状‍‍‍‍‍ 02 APIGW介绍及企业应用场景 03 总结 01 企业面对API与网关的现状‍ 在企业中&#xff0c;进行新的系统/应用/产品开发时&#xff0c;具有周密的流程&#xff1a;从需求分析、设计、开发、测试、发布与验收。所以&#xff0c;一…

Emacs之打开交互log(九十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

IDEA装上这3款ChatGPT插件,彻底炸裂!!

今天&#xff0c;给大家介绍3款好用的IntelliJ IDEA ChatGPT插件,各有千秋&#xff0c;可以帮我自动写代码&#xff0c;自动改善代码性能和安全并且生成视图对比&#xff0c;以及解释代码&#xff0c;优化代码&#xff0c;生成单元测试用例&#xff0c;更牛逼的是直接可以根据描…

13. Laravel 和 Vue-element-admin多语言配置

后端多语言 1. 安装&#xff0c; 并注册 composer require overtrue/laravel-lang:~6.0 # 添加以下行到 bootstrap/app.php $app->register(Overtrue\LaravelLang\TranslationServiceProvider::class);2. 修改默认语言为简体中文 # vim config/app.php locale > zh_CN…

『树莓派云台机器人』03. 利用SD卡进行树莓派的镜像烧录

目录 1. 下载镜像文件2. SD卡初始化与镜像烧录工具3. SD卡初始化过程4. 镜像烧录过程总结 欢迎关注 『树莓派云台机器人』 博客&#xff0c;持续更新中 欢迎关注 『树莓派云台机器人』 博客&#xff0c;持续更新中 1. 下载镜像文件 链接&#xff1a;https://pan.baidu.com/s/1…

我是普通人,我居然可以这样借力ChatGPT?(此文不卖课)

昨天写了一篇《程序员&#xff0c;如何借力ChatGPT&#xff1f;》&#xff0c;分享了借助AI&#xff1a; &#xff08;1&#xff09;撰写通用代码&#xff1b; &#xff08;2&#xff09;协助寻找BUG&#xff1b; &#xff08;3&#xff09;协助优化算法性能&#xff1b; &…

小白也能看懂的ChatGPT知识介绍

一、ChatGPT介绍 ChatGPT 是一款由 OpenAI 开发的人工智能技术驱动的语言模型应用。以下是 ChatGPT 的主要特点和功能&#xff1a; 自然语言处理&#xff1a;ChatGPT 可以识别和理解自然语言&#xff0c;包括英语、法语、德语、西班牙语等多种语言。它可以回答各种问题、提供各…

【Jetpack】Room + ViewModel + LiveData 综合使用 ( 核心要点说明 | 组合方式 | 代码示例 )

文章目录 一、Room ViewModel LiveData 框架使用核心要点1、Room 框架优化分析2、Google 官方建议的 Room ViewModel LiveData 架构3、Room 与 LiveData 结合使用要点4、Repository 层核心要点5、ViewModel Room 结合使用6、Activity 组件中 ViewModel 使用要点7、Room 框…

RWKV论文燃爆!将RNN崛起进行到底!可扩百亿级参数,与Transformer表现相当!

深度学习自然语言处理 原创作者&#xff1a;鸽鸽 万众期待的RWKV论文来啦&#xff01; 这股RNN崛起的“清流”&#xff0c;由民间开源组织发起&#xff0c;号称是第一个可扩展到百亿级参数的非transformer架构&#xff01; RWKV结合了RNN和Transformer的优势&#xff1a;一方面…

【送书】前端系列16集-vue3范型,vue-i18n-next,watch,watchEffect

送书活动&#xff1a;挑选1名粉丝同学哦 免费包邮送。截止时间&#xff1a;2023/5/26号 19 : 00参与底部评论区说说&#xff1a;请在评论中分享你的阅读收获。 中台落地手记——业务服务化与数据资产化 vue-i18n-next vue3 中使用 i18n 需要安装的是 [vue-i18n v9] 的版本 npm…

Nat Biotechnol –精准 CRISPR-Cas噬菌体疗法将为重症感染患者带来福音

治疗血液系统恶性肿瘤的化学药物常会引起骨髓功能抑制&#xff08;bone marrow suppression&#xff09;和胃肠道黏膜炎&#xff0c;并伴有肠道通透性增加。肠道细菌&#xff08;包括大肠杆菌&#xff09;从胃肠道易位是血流感染的常见原因。肠道细菌引起血流感染导致的死亡率为…

【这个问题纠结了我好多年】3dMax到底使用Intel还是AMD的CPU更好?

随着英特尔和 AMD 的新 CPU上市&#xff0c;是时候进行新一轮的硬件测试了。通过以极具竞争力的价格提供大量内核&#xff0c;AMD 已成为 CPU 领域的有力竞争者。作为回应&#xff0c;英特尔已开始增加其 CPU 中的内核数量。虽然它们提供的内核数量仍然不如 AMD&#xff0c;但它…

基于ESP32-CAM 和 OpenCV 设计的手势控制虚拟鼠标

概述 在本文中,我们将使用ESP32-CAM和OpenCV开发手势控制虚拟鼠标。ESP32 Camera Module和Python程序可用于无线控制鼠标跟踪和点击操作。 入门者必须具备 Python、图像处理、嵌入式系统以及物联网的丰富知识。首先,我们将了解如何控制鼠标跟踪和单击,以及运行 python 程序…