LLVM Cpu0 新后端6
想好好熟悉一下llvm开发一个新后端都要干什么,于是参考了老师的系列文章:
LLVM 后端实践笔记
代码在这里(还没来得及准备,先用网盘暂存一下):
链接: https://pan.baidu.com/s/1yLAtXs9XwtyEzYSlDCSlqw?pwd=vd6s 提取码: vd6s
之前的章节只实现了 int 和 32 位的 long 类型数据,这一章会新增一些更复杂的数据类型,比如 char, bool, short, long long,还会增加结构体,浮点,和向量类型。这一部分内容相对比较简单,其实这些类型也都是标准语言都支持的类型,所以 LLVM 自身已经实现了很大一部分功能,只要我们的后端不那么奇怪,就很容易填补缺失的内容。
目录
一、修改的文件
1.1 Cpu0ISelDAGToDAG.cpp
1.2 Cpu0ISelLowering.cpp/.h
1.3 Cpu0InstrInfo.td
1.4 Cpu0SEISelDAGToDAG.cpp/.h
1.5 MCTargetDesc/Cpu0InstPrinter.cpp/.h
二、实现结果
2.1 局部指针
2.2 char类型
2.3 bool类型
2.4 short
2.5 long long 类型
2.6 局部数组、结构体
2.7 全局数组、结构体
2.8 向量
2.9 cl指令
一、修改的文件
1.1 Cpu0ISelDAGToDAG.cpp
在SelectAddr接口内增加对于基址+常量偏移这种地址形式的处理,对于全局基址加常量偏移的情况,提取其基址和偏移。。
1.2 Cpu0ISelLowering.cpp/.h
有关于对 bool 类型的处理,这里增加了一些对 i1 类型 Promote 的合法化描述,告诉 LLVM 在遇到对 i1 类型的 extend 时要做 Promote。Promote 是将较小宽度的数据类型扩展成对应的能够支持的更宽的数据宽度类型,在指令选择的类型合法化阶段会起到作用。在 long long 实现中,在 Lowering 的位置还需要增加对 long long 类型的移位操作合法化。
覆盖一个函数 isOffsetFoldingLegal(),直接返回 false,避免带偏移的全局地址展开,Cpu0 和 Mips 一样无法处理这种情况。我们实现的 getAddrNonPIC() 方法中,将全局符号地址展开成一条加法指令,对地址的高低位做加法运算。所以实际上我们会将一条全局地址带偏移的寻址展开成加法运算 base,然后再把结果与 offset 相加的 DAG(在 Cpu0ISelDAGToDAG.cpp 中的 SelectAddr 中提取这种情况的 node Value,此时就已经是两个 add node 了)。
最后,还需要对向量类型的支持做一小部分改动,覆盖 getSetCCResultType() 方法,如果是向量类型,使用 VT.changeVectorElementTypeToInteger() 方法返回 CC 值。
1.3 Cpu0InstrInfo.td
到目前,因为我们添加数据类型的很多实现代码已经在公共 LLVM 代码中实现,所以实际上大多数修改都在 td 文件中。
新增一个 mem_ea 的操作数类型,这是一个 complexpattern,会定义其 encoding 操作和 printinst 等操作,它用来描述指令 pattern 中的地址表示;然后要定义一个 LEA_ADDiu 的模式,这是一个不会输出成指令的模式,它实际上是计算地址+偏移的结果,这和 sparc 处理器中的 LEA_ADDRi 是一样的效果。
新增 i8 和 i16 相关的 extend 类型以及对应的 ld/st,命名为 LB, LBu, SB, LH, LHu, SH。LB, LH 处理有符号的 i8/i16 类型 load,LBu, LHu 处理无符号的 i8/i16 类型 load,SB, SH 处理i8/i16 类型的store。
新增 CountLeading0 和 CountLeading1 的 pattern,用来选择到计算前导 0 和计算前导 1 的指令,llvm 内置了 ctlz 的 node(count leading zero),可以直接把 clz 指令接过去,不过对于 count leading 1 是没有对应的 node 的,不过可以通过先对值取反然后求前导 0 的方式实现前导 1 的计算,即 ctlz (not RC:$rb)。
因为 C 语言没有对求前导 0 和前导 1 的原生语法,所以实际上会使用 builtin 接口来实现,也就是说,在 C 语言描述中,为了实现这种功能,需要调用 __builtin_clz() 函数(ctls 就是先对参数取反再调用 ctlz 的 builtin),因为我们使用了内置的 node,所以这部分是 llvm 帮我们实现了。
1.4 Cpu0SEISelDAGToDAG.cpp/.h
定义了一个 selectAddESubE() 方法,用来处理带进位的加减法运算的指令选择。在 trySelect() 方法中,将对 ISD::SUBE, ISD::ADDE 的情况选择用 selectAddESubE() 来处理。
selectAddESubE() 方法为符合条件的 node 新增了一个操作数节点,该节点会读取状态字中进位是否是 1,并将结果叠加到运算中;在 Cpu032I 处理器中,使用 CMP 指令和 ANDi 指令来获取进位状态,在 Cpu032II 处理器中,则使用 SLT 指令直接判断进位。
另外,还要处理 SMUL_LOHI 和 UMUL_LOHI 节点,这是能够直接返回两个运算结果的节点(高低位)。
1.5 MCTargetDesc/Cpu0InstPrinter.cpp/.h
增加mem_ea 的printinst操作的实现。
二、实现结果
2.1 局部指针
int test_local_pointer() {int b = 3;int *p = &b;return *p;
}
addiu $sp, $sp, -8 # 扩栈addiu $2, $zero, 3 # 将3存到寄存器st $2, 4($sp) # 将其存到栈上addiu $2, $sp, 4 # 读出栈中局部变量的地址st $2, 0($sp) # 将这个地址存到栈上ld $2, 0($sp) # 读出这个地址ld $2, 0($2) # 读出地址里的内容addiu $sp, $sp, 8 # 回栈ret $lr # 返回
2.2 char类型
struct Date
{short year;char month;char day;char hour;char minute;char second;
};unsigned char b[4] = {'a', 'b', 'c', '\0'};int test_char()
{unsigned char a = b[1];char c = (char)b[1];struct Date date1 = {2021, (char)2, (char)27, (char)17, (char)22, (char)10};char m = date1.month;char s = date1.second;return 0;
}
addiu $sp, $sp, -24lui $2, %got_hi(b)addu $2, $2, $gpld $2, %got_lo(b)($2) # 与上边搭配加载全局变量b的首地址lbu $3, 1($2) # 计算b[1]的地址,存到寄存器3sb $3, 20($sp) # 将寄存器3内的地址存到栈上lbu $2, 1($2) # 再次计算b[1]的地址,存到寄存器2sb $2, 16($sp) # 将寄存器2内的地址存到栈上ld $2, %got($__const.test_char.date1)($gp)ori $2, $2, %lo($__const.test_char.date1) # 获取要写入局部变量对象的常量的地址lhu $3, 6($2) # 将偏移6处的内容load到寄存器3中,lhu是i16的,就是load范围是2字节lhu $4, 4($2) # 将偏移4处的内容load到寄存器4中,lhu是i16的,就是load范围是2字节shl $4, $4, 16 or $3, $4, $3 # 这两条是将上述load出来的两个2字节的内容拼成一个4字节的st $3, 12($sp) # 将这4字节存到栈上,也就是存放hour, minute, second到 date1lhu $3, 2($2) # 这里是相同的逻辑lhu $2, 0($2)shl $2, $2, 16or $2, $2, $3st $2, 8($sp) # 将这4字节存到栈上,也就是存放year, month, day到 date1lbu $2, 10($sp) # 从偏移10的位置读出date1.month(我们知道year, month, day在偏移8的位置,year两个字节,因此month在偏移10的位置,这里很正确)sb $2, 4($sp) # 将其存到栈上(m)lbu $2, 14($sp) # 从偏移14的位置读出date1.secondsb $2, 0($sp) # 将其存到栈上(s)addiu $2, $zero, 0addiu $sp, $sp, 24ret $lr
2.3 bool类型
bool test_load_bool()
{int a = 1;if (a < 0)return false;return true;
}
这里涉及到跳转我们当前可能编不过,下一节的内容加上之后我们就可以编过了,我们先提前看一下效果。
_Z14test_load_boolv:
# %bb.0:addiu $sp, $sp, -8addiu $2, $zero, 1st $2, 0($sp)ld $2, 0($sp)addiu $3, $zero, -1slt $2, $3, $2bne $2, $zero, $BB0_2nop
# %bb.1:addiu $2, $zero, 0sb $2, 7($sp) # 使用 sb 将 bool 类型的 0 写入栈jmp $BB0_3
$BB0_2:addiu $2, $zero, 1sb $2, 7($sp) # 使用 sb 将 bool 类型的 1 写入栈
$BB0_3:lbu $2, 7($sp)addiu $sp, $sp, 8ret $lr
2.4 short
int test_signed_char()
{char a = 0x80;int i = (signed int)a;i = i + 2; // i = (-128 + 2) = -126return i;
}int test_unsigned_char()
{unsigned char c = 0x80;unsigned int ui = (unsigned int)c;ui = ui + 2; // ui = (128 + 2) = 130return (int)ui;
}int test_signed_short()
{short a = 0x8000;int i = (signed int)a;i = i + 2; // i = (-32768 + 2) = -32766return i;
}int test_unsigned_short()
{unsigned short c = 0x8000;unsigned int ui = (unsigned int)c;ui = ui + 2; // ui = (32768 + 2) = 32770return (int)ui;
}
st_signed_short
...addiu $sp, $sp, -8ori $2, $zero, 32768sh $2, 4($sp)lh $2, 4($sp)st $2, 0($sp)ld $2, 0($sp)addiu $2, $2, 2st $2, 0($sp)ld $2, 0($sp)addiu $sp, $sp, 8ret $lr
...
test_unsigned_short:
...addiu $sp, $sp, -8ori $2, $zero, 32768sh $2, 4($sp)lhu $2, 4($sp)st $2, 0($sp)ld $2, 0($sp)addiu $2, $2, 2st $2, 0($sp)ld $2, 0($sp)addiu $sp, $sp, 8ret $lr
...
汇编还是很好理解的,这里就不进行详细的分析了。
2.5 long long 类型
long long test_longlong()
{long long a = 0x300000002;long long b = 0x100000001;int a1 = 0x30010000;int b1 = 0x20010000;long long c = a + b; // c = 0x00000004,00000003long long d = a - b; // d = 0x00000002,00000001long long e = a * b; // e = 0x00000005,00000002long long f = (long long)a1 * (long long)b1; // f = 0x00060050,01000000return (c+d+e+f); // (0x0006005b,01000006) = (393307,16777222)
}
addiu $sp, $sp, -56addiu $2, $zero, 2st $2, 52($sp) # a的低位addiu $2, $zero, 3st $2, 48($sp) # a的高位addiu $2, $zero, 1st $2, 44($sp) # b的低位st $2, 40($sp) # b的高位lui $2, 12289st $2, 36($sp) # a1lui $2, 8193st $2, 32($sp) # b1ld $2, 52($sp) # a的低位ld $3, 48($sp) # a的高位ld $4, 44($sp) # b的低位ld $5, 40($sp) # b的高位addu $3, $3, $5 # 高位相加addu $4, $2, $4 # 低位相加sltu $2, $4, $2 # 判断低位加法是否有进位addu $2, $3, $2 # 将进位与高位结果相加st $4, 28($sp) # 下同st $2, 24($sp)ld $2, 48($sp)ld $3, 52($sp)ld $4, 40($sp)ld $5, 44($sp)sltu $6, $3, $5subu $2, $2, $4subu $2, $2, $6subu $3, $3, $5st $3, 20($sp)st $2, 16($sp)ld $2, 48($sp)ld $3, 52($sp)ld $4, 44($sp)ld $5, 40($sp)mul $5, $3, $5multu $3, $4mflo $3mfhi $6addu $5, $6, $5mul $2, $2, $4addu $2, $5, $2st $3, 12($sp)st $2, 8($sp)ld $2, 36($sp)ld $3, 32($sp)mult $2, $3mflo $2mfhi $3st $2, 4($sp)st $3, 0($sp)ld $2, 28($sp)ld $3, 24($sp)ld $4, 20($sp)ld $5, 16($sp)addu $3, $3, $5addu $4, $2, $4sltu $2, $4, $2addu $2, $3, $2ld $3, 8($sp)ld $5, 12($sp)addu $5, $4, $5sltu $4, $5, $4addu $2, $2, $3addu $2, $2, $4ld $3, 4($sp)ld $4, 0($sp)addu $2, $2, $4addu $3, $5, $3sltu $4, $3, $5addu $2, $2, $4addiu $sp, $sp, 56ret $lr
2.6 局部数组、结构体
与2.2中的局部结构体类似。
2.7 全局数组、结构体
struct Date
{int year;int month;int day;
};struct Date date = {2021, 2, 27};
int a[3] = {2021, 2, 27};int test_struct()
{int day = date.day;int i = a[1];return (i+day); // 2 + 27 = 29
}
addiu $sp, $sp, -8lui $2, %got_hi(date)addu $2, $2, $gpld $2, %got_lo(date)($2) # 从got表中取全局变量date的地址ld $2, 8($2) # 从偏移8的地方load出date.day,(year和month各占4字节)st $2, 4($sp) # 存到栈中(day)lui $2, %got_hi(a) # 下同addu $2, $2, $gpld $2, %got_lo(a)($2)ld $2, 4($2)st $2, 0($sp)ld $2, 0($sp)ld $3, 4($sp)addu $2, $2, $3addiu $sp, $sp, 8ret $lr
2.8 向量
typedef long vector8long __attribute__((__vector_size__(32)));
typedef long vector8short __attribute__((__vector_size__(16)));int test_cmplt_short()
{volatile vector8short a0 = {0, 1, 2, 3};volatile vector8short b0 = {2, 2, 2, 2};volatile vector8short c0;c0 = a0 < b0;return (int)(c0[0] + c0[1] + c0[2] + c0[3]);
}int test_cmplt_long()
{volatile vector8long a0 = {2, 2, 2, 2, 1, 1, 1, 1};volatile vector8long b0 = {1, 1, 1, 1, 2, 2, 2, 2};volatile vector8long c0;c0 = a0 < b0;return (c0[0] + c0[1] + c0[2] + c0[3] + c0[4] + c0[5] + c0[6] + c0[7]);
}
下述是test_cmplt_short函数的汇编,我们看个稍微短一点的:
addiu $sp, $sp, -64st $10, 60($sp) # 4-byte Folded Spillst $9, 56($sp) # 4-byte Folded Spilladdiu $2, $zero, 3st $2, 44($sp)addiu $3, $zero, 2st $3, 40($sp)addiu $2, $zero, 1st $2, 36($sp)addiu $2, $zero, 0st $2, 32($sp)st $3, 28($sp)st $3, 24($sp)st $3, 20($sp)st $3, 16($sp)ld $3, 44($sp)ld $4, 40($sp)ld $5, 36($sp)ld $6, 32($sp)ld $7, 28($sp)ld $8, 24($sp)ld $9, 20($sp)ld $10, 16($sp)slt $6, $6, $10subu $6, $2, $6slt $5, $5, $9subu $5, $2, $5slt $4, $4, $8subu $4, $2, $4slt $3, $3, $7subu $2, $2, $3st $2, 12($sp)st $4, 8($sp)st $5, 4($sp)st $6, 0($sp)ld $2, 12($sp)ld $2, 8($sp)ld $2, 4($sp)ld $2, 0($sp)ld $3, 12($sp)ld $3, 8($sp)ld $3, 0($sp)ld $3, 4($sp)addu $2, $2, $3ld $3, 12($sp)ld $3, 4($sp)ld $3, 0($sp)ld $3, 8($sp)addu $2, $2, $3ld $3, 8($sp)ld $3, 4($sp)ld $3, 0($sp)ld $3, 12($sp)addu $2, $2, $3ld $9, 56($sp) # 4-byte Folded Reloadld $10, 60($sp) # 4-byte Folded Reloadaddiu $sp, $sp, 64ret $lr
其实整体逻辑是很简单的。
2.9 cl指令
int countLeadingZero() {int a, b;b = __builtin_clz(a);return b;
}int countLeadingOne() {int a, b;b = __builtin_clz(~a);return b;
}
countLeadingZero:addiu $sp, $sp, -8ld $2, 4($sp)clz $2, $2st $2, 0($sp)ld $2, 0($sp)addiu $sp, $sp, 8ret $lrcountLeadingOne:addiu $sp, $sp, -8ld $2, 4($sp)clo $2, $2st $2, 0($sp)ld $2, 0($sp)addiu $sp, $sp, 8ret $lr
相关文章:
LLVM Cpu0 新后端6
想好好熟悉一下llvm开发一个新后端都要干什么,于是参考了老师的系列文章: LLVM 后端实践笔记 代码在这里(还没来得及准备,先用网盘暂存一下): 链接: https://pan.baidu.com/s/1yLAtXs9XwtyEzYSlDCSlqw?…...
GAT1399协议分析(9)--图像上传
一、官方定义 二、wirechark实例 有前面查询的基础,这个接口相对简单很多。 请求: 文本化: POST /VIID/Images HTTP/1.1 Host: 10.0.201.56:31400 User-Agent: python-requests/2.32.3 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive content-type:…...
Spring ApplicationContext的getBean方法
Spring ApplicationContext的getBean方法 在Spring框架的ApplicationContext中,getBean(Class<T> requiredType)方法可以接受一个类类型参数,这个参数可以是接口类也可以是实现类。 使用接口类: 如果requiredType是一个接口,…...
自然语言处理(NLP)—— 自动摘要
自动摘要是一种将长文本信息浓缩为短文本的技术,旨在保留原文的主要信息和意义。 1 自动摘要的第一种方法 它的第一种方法是基于理解的,受认知科学和人工智能的启发。 在这个方法中,我们首先建立文本的语义表示,这可以理解为文本…...
Spring RestClient报错:400 Bad Request : [no body]
我项目采用微服务架构,所以各服务之间通过Spring RestClient远程调用,本来一直工作得好好的,昨天突然发现远程调用一直报错,错误详情如下: org.springframework.web.client.HttpClientErrorException$BadRequest: 400…...
【数据结构】 -- 堆 (堆排序)(TOP-K问题)
引入 要学习堆,首先要先简单的了解一下二叉树,二叉树是一种常见的树形数据结构,每个节点最多有两个子节点,通常称为左子节点和右子节点。它具有以下特点: 根节点(Root):树的顶部节…...
C#面:XML与 HTML 的主要区别是什么
C# XML与HTML有以下几个主要区别: 用途不同:XML(eXtensible Markup Language)是一种用于存储和传输数据的标记语言,它的主要目的是描述数据的结构和内容。HTML(HyperText Markup Language)是一…...
java并发-如何保证线程按照顺序执行?
【readme】 使用只有单个线程的线程池(最简单)Thread.join() 可重入锁 ReentrantLock Condition 条件变量(多个) ; 原理如下: 任务1执行前在锁1上阻塞;执行完成后在锁2上唤醒;任务…...
PyCharm中 Fitten Code插件的使用说明一
一. 简介 Fitten Code插件是是一款由非十大模型驱动的 AI 编程助手,它可以自动生成代码,提升开发效率,帮您调试 Bug,节省您的时间,另外还可以对话聊天,解决您编程碰到的问题。 前一篇文章学习了 PyCharm…...
Polar Web【简单】PHP反序列化初试
Polar Web【简单】PHP反序列化初试 Contents Polar Web【简单】PHP反序列化初试思路EXP手动脚本PythonGo 运行&总结 思路 启动环境,显示下图中的PHP代码,于是展开分析: 首先发现Easy类中有魔术函数 __wakeup() ,实现的是对成员…...
树莓派4B 零起点(二) 树莓派 更换软件源和软件仓库
目录 一、准备工作,查看自己的树莓派版本 二、安装HTTPS支持 三、更换为清华源 1、更换Debian软件源 2,更换Raspberrypi软件仓库 四、进行软件更新 接前章,我们的树莓派已经启动起来了,接下来要干的事那就是更换软件源和软件…...
Pytorch 实现目标检测二(Pytorch 24)
一 实例操作目标检测 下面通过一个具体的例子来说明锚框标签。我们已经为加载图像中的狗和猫定义了真实边界框,其中第一个 元素是类别(0代表狗,1代表猫),其余四个元素是左上角和右下角的(x, y)轴坐标(范围…...
如何使用Python中的列表解析(list comprehension)进行高效列表操作
Python中的列表解析(list comprehension)是一种创建列表的简洁方法,它可以在单行代码中执行复杂的循环和条件逻辑。列表解析提供了一种快速且易于阅读的方式来生成新的列表。 以下是一些使用列表解析进行高效列表操作的示例: 1.…...
java使用websocket遇到的问题
java使用websocket的bug 1 websocket连接正常但是收不到服务端发出的消息java的websocket并发的时候导致连接断开(看着连接是正常的,但是实际上已经断开) 1 websocket连接正常但是收不到服务端发出的消息 java的websocket并发的时候导致连接断…...
[Cloud Networking] Layer 2
文章目录 1. 什么是Mac Address?2. 如何查找MAC地址?3. 二层数据交换4. [Layer 2 Protocol](https://blog.csdn.net/settingsun1225/article/details/139552315) 1. 什么是Mac Address? MAC 地址是计算机的唯一48位硬件编码,嵌入到网卡中。 MAC地址也…...
[240609] qwen2 发布,在 Ollama 已可用 | 采用语言模型构建通用 AGI(2020年8月)
目录 qwen2 发布,在 Ollama 已可用Qwen2 模型概览 (基于 Ollama 网站信息)一、模型介绍二、模型参数三、支持语言 (除英语和中文外)四、模型性能五、许可证六、数据支撑: 采用语言模型构建通用 AGI qwen2 发布,在 Ollama 已可用 Qwen2 模型概览 (基于 O…...
赶紧收藏!2024 年最常见 20道分布式、微服务面试题(五)
上一篇地址:赶紧收藏!2024 年最常见 20道分布式、微服务面试题(四)-CSDN博客 九、在分布式系统中,如何保证数据一致性? 在分布式系统中保证数据一致性是一个复杂的问题,因为分布式系统由多个独…...
为什么Kubernetes(K8S)弃用Docker:深度解析与未来展望
为什么Kubernetes弃用Docker:深度解析与未来展望 🚀 为什么Kubernetes弃用Docker:深度解析与未来展望摘要引言正文内容(详细介绍)什么是 Kubernetes?什么是 Docker?Kubernetes 和 Docker 的关系…...
软件游戏提示msvcp120.dll丢失的解决方法,总结多种靠谱的解决方法
在电脑使用过程中,我们可能会遇到一些错误提示,其中之一就是“找不到msvcp120.dll”。那么,msvcp120.dll是什么?它对电脑有什么影响?有哪些解决方法?本文将从以下几个方面进行探讨。 一,了解msv…...
使用kafka tools工具连接带有用户名密码的kafka
使用kafka tools工具连接带有用户名密码的kafka 创建kafka连接,配置zookeeper 在Security选择Type类型为SASL Plaintext 在Advanced页面添加如下图红框框住的内容 在JAAS_Config加上如下配置 需要加的配置: org.apache.kafka.common.security.plain.Pla…...
[个人感悟] Java基础问题应该考察哪些问题?
前言 “一切代码无非是数据结构和算法流程的结合体.” 忘了最初是在何处看见这句话了, 这句话, 对于Java基础的考察也是一样. 正如这句话所说, 我们对于基础的考察主要考察, 数据结构, 集合类型结构, 异常类型, 已经代码的调用和语法关键字. 其中数据结构和集合类型结构是重点…...
MySQL-主从复制
1、主从复制的理解 在工作用常见Redis作为缓存与MySQL一起使用。当有请求时,首先会从缓存中进行查找,如果存在就直接取出,否则访问数据库,这样 提升了读取的效率,也减少了对后台数据库的访问压力。Redis的缓存架构时高…...
开发没有尽头,尽力既是完美
最近遇到了一些难题,开发系统总有一些地方没有考虑周全,偏偏用户使用的时候“完美复现”了这个隐藏的Bug...... 讲道理创业一年之久为了生存,我一直都有在做复盘,复盘的核心就是:如何提升营收、把控开发质量࿰…...
【手推公式】如何求SDE的解(附录B)
【手推公式】如何求SDE的解(附录B) 核心思路:不直接求VE和VP的SDE的解xt,而是求xt的期望和方差,从而写出x0到xt的条件分布形式(附录B) 论文:Score-Based Generative Modeling throug…...
STM32F103单片机工程移植到航顺单片机HK32F103注意事项
一、简介 作为国内MCU厂商中前三阵营之一的航顺芯片,建立了世界首创超低功耗7nA物联网、万物互联核心处理器浩瀚天际10X系列平台,接受代理商/设计企业/方案商定制低于自主研发十倍以上成本,接近零风险自主品牌产品,芯片设计完成只…...
Llama模型家族之Stanford NLP ReFT源代码探索 (四)Pyvene论文学习
LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (一) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (二) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (三) 基于 LlaMA…...
rapidjson 打包过程插入对象
开发过程中遇到一种情况,在打包过程中插入一个字符串(里面是json对象), 官方文档 没看到相关例子,不知道是不是自己粗心没找到。方法RawValue其实是一个通用打包方法,一般情况我们都调用的是String()、Int(…...
NVeloDocx一个基于NVelocity的word模版引擎
NVeloDocx是一个基于NVelocity的Word模版引擎,目前主要是用于E6低代码开发平台供用户轻松制作各种Word报告模版。 有以下优点: 1、完全的NVelocity语法; 2、直接在Word中写NVelocity脚本,使用非常非常方便; 3、完全兼…...
【JavaEE】Spring IoCDI详解
一.基本概念 1.Ioc基本概念 Ioc: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器. 什么是控制反转呢? 也就是控制权反转. 什么的控制权发发了反转? 获得依赖对象的过程被反转了也就是说, 当需要某个对象时, 传统开发模式中需要自己通…...
Bean的作用域
singleton : 单例,IOC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。 prototype : 原型,每次获取都会创建一个新的 bean 实例。也就是说,连续 getBean() 两次,得到的是不同…...
wordpress控件图标/百度 营销推广怎么操作
文章讲的是未来最赚钱的行业三甲,必须必是它们,随着云计算、大数据的发展,人工智能的研发也已经越来越精进,虽然人工智能尚处在初始阶段,但不可否认这个领域存在着大量的商机。 商机大的地方,一定少不了各大…...
做网站维护前景/宁波专业seo服务
上午主要是开会部门岗位调整,下午开会明确基线工作,计划讨论BS采用统一用户权限方式实现,单独做一个独立的平台,感觉这种松耦合的实现方式很好,原来老的平台就是因为耦合太严重才出现现在这样各种问题。 终于要从delph…...
安徽省建设干部学校网站/整站seo
在做provider_admin的过程中,大家可以发现有比较多框架相关的配置文件和框架运行过程中的文件操作,这篇文章集中讨论下这些文件的操作,总的文件分下面的几类,其中和应用相关的按框架提供的example应用举例。 1、框架的全局配置文…...
中搜网站提交/策划网络营销活动
QList是一种表示链表的模板类。QList是Qt的一种泛型容器类。它以链表方式存储一组值,并能对这组数据进行快速索引,还提供了快速插入和删除等操作。QList、QLinkedList和QVector提供的操作极其相似:*对大多数操作来说,我们用QList就…...
武汉 网站 合作伙伴/爱站网ip反域名查询
日常使用PHP开发较多,但是有些地方PHP的语言的瓶颈就显露出来了,例如,同样是抓取一个网站的内容,使用PHP需要较为复杂的正则匹配,效率较为低下。python具有丰富的类库,拿过来直接可以使用,功能强…...
做网站有什么用/卡点视频软件下载
在JAVA编程中,有这样一个问题:类A引用了类B,那么如果运行时没有类B,类A会不会调用成功,而不抛异常? 答案是,有可能运行成功,而不抛异常。 例子1: ClassA.java packag…...