Architecture Lab:Part C【流水线通用原理/Y86-64的流水线实现/实现IIADDQ指令】

目录

任务描述

知识回顾

流水线通用原理

Y86-64流水线实现(PIPE-与PIPE)

开始实验

IIADDQ指令的添加

优化 ncopy.ys

仅用第四章知识,CEP=11.55

8x1展开,CPE=9.35

8x1展开+2x1展开+消除气泡,CPE=8.10 


流水线化通过让不同的阶段并行操作,改进了系统的吞吐量性能。

在任意一个给定的时刻,多条指令被不同的阶段处理。在引入这种并行性的过程中,我们必须非常小心,以提供与程序的顺序执行相同的程序级行为。通过重新调整SEQ各个部分的顺序,引入流水线,我们得到SEQ+,接着添加流水线寄存器,创建出 PIPE-流水线。

然后,添加了转发逻辑,加速了将结果从一条指令发送到另一条指令,从而提高了流水线的性能。有几种特殊情况需要额外的流水线控制逻辑来暂停或取消一些流水线阶段。

任务描述

Your task in Part C is to modify ncopy.ys and pipe-full.hcl with the goal of making ncopy.ys
run as fast as possible.

翻译过来就是:

第一步,首先要把 pipe-full.hcl 中加入 iaddq 指令。

第二步,优化 ncopy.ys ,使CEP降到7.5

知识回顾

流水线通用原理

就像下图流水线图上方指明的那样,流水线阶段之间的指令转移是由时钟信号来控制的。每隔120ps, 信号从0上升至1,开始下一组流水线阶段的计算。

 时间=239时,是时钟上升沿到来的前一刻,此时组合逻辑A已经完成了指令I2(蓝色),正在等待寄存器打入脉冲(即时间=240时的上升沿)。同理,组合逻辑B已经完成了指令I1(深灰色),正在等待寄存器打入脉冲(即时间=240时的上升沿)。

 时间=241时,是时钟上升沿到来之后,指令I2(蓝色)的结果刚刚打入寄存器。指令I1(深灰色)的结果也刚刚打入寄存器。

 时间=300时,是时钟上升沿到来之后,指令I2(蓝色)正在组合逻辑B中进行计算。指令I1(深灰色)正在组合逻辑C中进行计算。新加入的指令I3(浅灰色)正在组合逻辑A中进行计算。

Y86-64流水线实现(PIPE-与PIPE)

首先,对顺序的SEQ处理器做一点小的改动,将 PC的计算挪到第一阶段(取指)。原因:方便流水线源源不断的给出新指令。

然后,在各个阶段之间加上流水线寄存器。

开始实验

IIADDQ指令的添加

IIADDQ指令的添加与Part B一样。唯一要注意的是记得改条件码(set_cc)。

char simname[] = "Y86-64 Processor: pipe-full.hcl";
#include <stdio.h>
#include "isa.h"
#include "pipeline.h"
#include "stages.h"
#include "sim.h"
int sim_main(int argc, char *argv[]);
int main(int argc, char *argv[]){return sim_main(argc,argv);}
long long gen_f_pc()
{return ((((ex_mem_curr->icode) == (I_JMP)) & !(ex_mem_curr->takebranch)) ? (ex_mem_curr->vala) : ((mem_wb_curr->icode) == (I_RET)) ? (mem_wb_curr->valm) : (pc_curr->pc));
}long long gen_f_icode()
{return ((imem_error) ? (I_NOP) : (imem_icode));
}long long gen_f_ifun()
{return ((imem_error) ? (F_NONE) : (imem_ifun));
}long long gen_instr_valid()
{return ((if_id_next->icode) == (I_NOP) || (if_id_next->icode) == (I_HALT) || (if_id_next->icode) == (I_RRMOVQ) || (if_id_next->icode)== (I_IRMOVQ) || (if_id_next->icode) == (I_RMMOVQ) || (if_id_next->icode) == (I_MRMOVQ) || (if_id_next->icode) == (I_ALU)|| (if_id_next->icode) == (I_JMP) || (if_id_next->icode) == (I_CALL)|| (if_id_next->icode) == (I_RET) || (if_id_next->icode) == (I_PUSHQ) || (if_id_next->icode) == (I_POPQ) || (if_id_next->icode)== (I_IADDQ));
}long long gen_f_stat()
{return ((imem_error) ? (STAT_ADR) : !(instr_valid) ? (STAT_INS) : ((if_id_next->icode) == (I_HALT)) ? (STAT_HLT) : (STAT_AOK));
}long long gen_need_regids()
{return ((if_id_next->icode) == (I_RRMOVQ) || (if_id_next->icode) == (I_ALU) || (if_id_next->icode) == (I_PUSHQ) || (if_id_next->icode)== (I_POPQ) || (if_id_next->icode) == (I_IRMOVQ) || (if_id_next->icode) == (I_RMMOVQ) || (if_id_next->icode) == (I_MRMOVQ) || (if_id_next->icode) == (I_IADDQ));
}long long gen_need_valC()
{return ((if_id_next->icode) == (I_IRMOVQ) || (if_id_next->icode) == (I_RMMOVQ) || (if_id_next->icode) == (I_MRMOVQ) || (if_id_next->icode) == (I_JMP) || (if_id_next->icode) == (I_CALL) || (if_id_next->icode) == (I_IADDQ));
}long long gen_f_predPC()
{return (((if_id_next->icode) == (I_JMP) || (if_id_next->icode) == (I_CALL)) ? (if_id_next->valc) : (if_id_next->valp));
}long long gen_d_srcA()
{return (((if_id_curr->icode) == (I_RRMOVQ) || (if_id_curr->icode) == (I_RMMOVQ) || (if_id_curr->icode) == (I_ALU) || (if_id_curr->icode)== (I_PUSHQ)) ? (if_id_curr->ra) : ((if_id_curr->icode) == (I_POPQ) || (if_id_curr->icode) == (I_RET)) ? (REG_RSP) : (REG_NONE));
}long long gen_d_srcB()
{return (((if_id_curr->icode) == (I_ALU) || (if_id_curr->icode) == (I_RMMOVQ) || (if_id_curr->icode) == (I_MRMOVQ) || (if_id_curr->icode) == (I_IADDQ)) ? (if_id_curr->rb) : ((if_id_curr->icode) == (I_PUSHQ) || (if_id_curr->icode) == (I_POPQ)|| (if_id_curr->icode) == (I_CALL) || (if_id_curr->icode) == (I_RET)) ? (REG_RSP) : (REG_NONE));
}long long gen_d_dstE()
{return (((if_id_curr->icode) == (I_RRMOVQ) || (if_id_curr->icode) == (I_IRMOVQ) || (if_id_curr->icode) == (I_ALU) || (if_id_curr->icode)== (I_IADDQ)) ? (if_id_curr->rb) : ((if_id_curr->icode) == (I_PUSHQ) || (if_id_curr->icode) == (I_POPQ) || (if_id_curr->icode)== (I_CALL) || (if_id_curr->icode) == (I_RET)) ? (REG_RSP) : (REG_NONE));
}long long gen_d_dstM()
{return (((if_id_curr->icode) == (I_MRMOVQ) || (if_id_curr->icode) == (I_POPQ)) ? (if_id_curr->ra) : (REG_NONE));
}long long gen_d_valA()
{return (((if_id_curr->icode) == (I_CALL) || (if_id_curr->icode) == (I_JMP)) ? (if_id_curr->valp) : ((id_ex_next->srca) == (ex_mem_next->deste)) ? (ex_mem_next->vale) : ((id_ex_next->srca)== (ex_mem_curr->destm)) ? (mem_wb_next->valm) : ((id_ex_next->srca) == (ex_mem_curr->deste)) ? (ex_mem_curr->vale): ((id_ex_next->srca) == (mem_wb_curr->destm)) ? (mem_wb_curr->valm): ((id_ex_next->srca) == (mem_wb_curr->deste)) ? (mem_wb_curr->vale): (d_regvala));
}long long gen_d_valB()
{return (((id_ex_next->srcb) == (ex_mem_next->deste)) ? (ex_mem_next->vale) : ((id_ex_next->srcb) == (ex_mem_curr->destm)) ? (mem_wb_next->valm) : ((id_ex_next->srcb) == (ex_mem_curr->deste)) ? (ex_mem_curr->vale) : ((id_ex_next->srcb) == (mem_wb_curr->destm)) ? (mem_wb_curr->valm) : ((id_ex_next->srcb) == (mem_wb_curr->deste)) ? (mem_wb_curr->vale) : (d_regvalb));
}long long gen_aluA()
{return (((id_ex_curr->icode) == (I_RRMOVQ) || (id_ex_curr->icode) == (I_ALU)) ? (id_ex_curr->vala) : ((id_ex_curr->icode) == (I_IRMOVQ)|| (id_ex_curr->icode) == (I_RMMOVQ) || (id_ex_curr->icode) == (I_MRMOVQ) || (id_ex_curr->icode) == (I_IADDQ)) ? (id_ex_curr->valc) : ((id_ex_curr->icode) == (I_CALL) || (id_ex_curr->icode) == (I_PUSHQ)) ? -8 : ((id_ex_curr->icode) == (I_RET) || (id_ex_curr->icode) == (I_POPQ)) ? 8 : 0);
}long long gen_aluB()
{return (((id_ex_curr->icode) == (I_RMMOVQ) || (id_ex_curr->icode) == (I_MRMOVQ) || (id_ex_curr->icode) == (I_ALU) || (id_ex_curr->icode)== (I_CALL) || (id_ex_curr->icode) == (I_PUSHQ) || (id_ex_curr->icode) == (I_RET) || (id_ex_curr->icode) == (I_POPQ)|| (id_ex_curr->icode) == (I_IADDQ)) ? (id_ex_curr->valb) : ((id_ex_curr->icode) == (I_RRMOVQ) || (id_ex_curr->icode) == (I_IRMOVQ)) ? 0 : 0);
}long long gen_alufun()
{return (((id_ex_curr->icode) == (I_ALU)) ? (id_ex_curr->ifun) : (A_ADD));
}long long gen_set_cc()
{return (((((id_ex_curr->icode) == (I_ALU)) & !((mem_wb_next->status)== (STAT_ADR) || (mem_wb_next->status) == (STAT_INS) || (mem_wb_next->status) == (STAT_HLT))) & !((mem_wb_curr->status)== (STAT_ADR) || (mem_wb_curr->status) == (STAT_INS) || (mem_wb_curr->status) == (STAT_HLT))) | ((id_ex_curr->icode) == (I_IADDQ)));
}long long gen_e_valA()
{return (id_ex_curr->vala);
}long long gen_e_dstE()
{return ((((id_ex_curr->icode) == (I_RRMOVQ)) & !(ex_mem_next->takebranch)) ? (REG_NONE) : (id_ex_curr->deste));
}long long gen_mem_addr()
{return (((ex_mem_curr->icode) == (I_RMMOVQ) || (ex_mem_curr->icode) == (I_PUSHQ) || (ex_mem_curr->icode) == (I_CALL) || (ex_mem_curr->icode) == (I_MRMOVQ)) ? (ex_mem_curr->vale) : ((ex_mem_curr->icode) == (I_POPQ) || (ex_mem_curr->icode) == (I_RET)) ? (ex_mem_curr->vala) : 0);
}long long gen_mem_read()
{return ((ex_mem_curr->icode) == (I_MRMOVQ) || (ex_mem_curr->icode) == (I_POPQ) || (ex_mem_curr->icode) == (I_RET));
}long long gen_mem_write()
{return ((ex_mem_curr->icode) == (I_RMMOVQ) || (ex_mem_curr->icode) == (I_PUSHQ) || (ex_mem_curr->icode) == (I_CALL));
}long long gen_m_stat()
{return ((dmem_error) ? (STAT_ADR) : (ex_mem_curr->status));
}long long gen_w_dstE()
{return (mem_wb_curr->deste);
}long long gen_w_valE()
{return (mem_wb_curr->vale);
}long long gen_w_dstM()
{return (mem_wb_curr->destm);
}long long gen_w_valM()
{return (mem_wb_curr->valm);
}long long gen_Stat()
{return (((mem_wb_curr->status) == (STAT_BUB)) ? (STAT_AOK) : (mem_wb_curr->status));
}long long gen_F_bubble()
{return 0;
}long long gen_F_stall()
{return ((((id_ex_curr->icode) == (I_MRMOVQ) || (id_ex_curr->icode) == (I_POPQ)) & ((id_ex_curr->destm) == (id_ex_next->srca) || (id_ex_curr->destm) == (id_ex_next->srcb))) | ((I_RET) == (if_id_curr->icode) || (I_RET) == (id_ex_curr->icode) || (I_RET)== (ex_mem_curr->icode)));
}long long gen_D_stall()
{return (((id_ex_curr->icode) == (I_MRMOVQ) || (id_ex_curr->icode) == (I_POPQ)) & ((id_ex_curr->destm) == (id_ex_next->srca) || (id_ex_curr->destm) == (id_ex_next->srcb)));
}long long gen_D_bubble()
{return ((((id_ex_curr->icode) == (I_JMP)) & !(ex_mem_next->takebranch))| (!(((id_ex_curr->icode) == (I_MRMOVQ) || (id_ex_curr->icode) == (I_POPQ)) & ((id_ex_curr->destm) == (id_ex_next->srca) || (id_ex_curr->destm) == (id_ex_next->srcb))) & ((I_RET) == (if_id_curr->icode) || (I_RET) == (id_ex_curr->icode) || (I_RET)== (ex_mem_curr->icode))));
}long long gen_E_stall()
{return 0;
}long long gen_E_bubble()
{return ((((id_ex_curr->icode) == (I_JMP)) & !(ex_mem_next->takebranch))| (((id_ex_curr->icode) == (I_MRMOVQ) || (id_ex_curr->icode) == (I_POPQ)) & ((id_ex_curr->destm) == (id_ex_next->srca) || (id_ex_curr->destm) == (id_ex_next->srcb))));
}long long gen_M_stall()
{return 0;
}long long gen_M_bubble()
{return (((mem_wb_next->status) == (STAT_ADR) || (mem_wb_next->status)== (STAT_INS) || (mem_wb_next->status) == (STAT_HLT)) | ((mem_wb_curr->status) == (STAT_ADR) || (mem_wb_curr->status) == (STAT_INS) || (mem_wb_curr->status) == (STAT_HLT)));
}long long gen_W_stall()
{return ((mem_wb_curr->status) == (STAT_ADR) || (mem_wb_curr->status)== (STAT_INS) || (mem_wb_curr->status) == (STAT_HLT));
}long long gen_W_bubble()
{return 0;
}

改完之后,在pipe目录下:

make clean

make VERSION=full

然后测试:

./psim -t ../y86-code/asumi.yo
cd ../ptest; make SIM=../pipe/psim
cd ../ptest; make SIM=../pipe/psim TFLAGS=-i

发现都过了,那么IIADDQ指令就添加对了。接下来优化 ncopy.ys

优化 ncopy.ys

先从ptest目录回到pipe目录,测试一下基准程序:

cd ../pipe

 ./correctness.pl(测试正确性)

./benchmark.pl(给出得分)

基准程序,CEP=15.18

现在进行一些优化。

仅用第四章知识,CEP=11.55

1. 29行移到33行的位置,去掉原本的第33行。(效果:CPE降1)

2. 使用iaddq指令替换所有的addq指令

3. 把25行跳转改为传送?

        不行

        原因是,原句含义为“如果R[%r10]>0,那么R[%rax]++”。改为“%r11赋值为1,测试%r10,如果≤0,将立即数0传送给%r11,addq %r11,%rax,将r11恢复为立即数1以备下次循环使用”,测试结果是,跳转改为传送,可将CEP降低0.44,但“将r11恢复为立即数1以备下次循环使用”又将CEP提高了1.

4. 第20行,由于跳转策略,所以默认给它Loop(效果:CPE降0.14)

至此,用我们在第四章学到的知识,CEP=11.55,代码如下:

# You can modify this portionxorq %rax,%rax		# count = 0;andq %rdx,%rdx		# len <= 0?jg Loop		        # if so, goto Done:retLoop:	mrmovq (%rdi), %r10	# read val from src...rmmovq %r10, (%rsi)	# ...and store it to dstandq %r10, %r10		# val <= 0?jle NoAdd1iaddq $1, %raxNoAdd1:	iaddq $8, %rdi		# src++iaddq $8, %rsi		# dst++iaddq $-1, %rdx		# length--jg Loop			    # if so, goto Loop:

 

然后用第五章的循环展开方法继续优化。

8x1展开,CPE=9.35
# You can modify this portionxorq %rax,%rax		    # count = 0;andq %rdx, %rdxjg JudgeretJudge:	iaddq $-8, %rdxjge Loop6iaddq $8, %rdxLoop1:mrmovq (%rdi), %r10	    # read val from src...rmmovq %r10, (%rsi)	    # ...and store it to dstandq %r10, %r10		    # val <= 0?jle NoAddiaddq $1, %rax
NoAdd:iaddq $8, %rdiiaddq $8, %rsiiaddq $-1, %rdxjg Loop1		retLoop6:	mrmovq (%rdi), %r10	    # read val from src...rmmovq %r10, (%rsi)	    # ...and store it to dstandq %r10, %r10		    # val <= 0?jle NoAdd1iaddq $1, %rax
NoAdd1:	mrmovq 8(%rdi), %r10	# read val from src...rmmovq %r10, 8(%rsi)	# ...and store it to dstandq %r10, %r10 	    # val <= 0?jle NoAdd2iaddq $1, %rax
NoAdd2:	mrmovq 16(%rdi), %r10	# read val from src...rmmovq %r10, 16(%rsi)	# ...and store it to dstandq %r10, %r10		    # val <= 0?jle NoAdd3iaddq $1, %rax
NoAdd3:	mrmovq 24(%rdi), %r10	# read val from src...rmmovq %r10, 24(%rsi)	# ...and store it to dstandq %r10, %r10		    # val <= 0?jle NoAdd4iaddq $1, %rax
NoAdd4:	mrmovq 32(%rdi), %r10	# read val from src...rmmovq %r10, 32(%rsi)	# ...and store it to dstandq %r10, %r10		    # val <= 0?jle NoAdd5iaddq $1, %rax
NoAdd5:	mrmovq 40(%rdi), %r10	# read val from src...rmmovq %r10, 40(%rsi)	# ...and store it to dstandq %r10, %r10		    # val <= 0?jle NoAdd6iaddq $1, %rax
NoAdd6:	mrmovq 48(%rdi), %r10	# read val from src...rmmovq %r10, 48(%rsi)	# ...and store it to dstandq %r10, %r10		    # val <= 0?jle NoAdd7iaddq $1, %rax
NoAdd7:	mrmovq 56(%rdi), %r10	# read val from src...rmmovq %r10, 56(%rsi)	# ...and store it to dstandq %r10, %r10		    # val <= 0?jle NoAdd8iaddq $1, %rax
NoAdd8:	iaddq $64, %rdiiaddq $64, %rsiandq %rdx, %rdxjg Judge		        

8x1展开+2x1展开+消除气泡,CPE=8.10 
# You can modify this portion#xorq %rax,%rax		# count = 0;andq %rdx, %rdxjg JudgeretUnfold8:	mrmovq (%rdi), %r10	# read val from src...mrmovq 8(%rdi), %r11	# read val from src...mrmovq 16(%rdi), %r12	# read val from src...mrmovq 24(%rdi), %r13	# read val from src...rmmovq %r10, (%rsi)	# ...and store it to dstrmmovq %r11, 8(%rsi)	# ...and store it to dstrmmovq %r12, 16(%rsi)	# ...and store it to dstrmmovq %r13, 24(%rsi)	# ...and store it to dstandq %r10, %r10		# val <= 0?jle NoAdd1iaddq $1, %rax
NoAdd1:	andq %r11, %r11 	# val <= 0?jle NoAdd2iaddq $1, %rax
NoAdd2:	andq %r12, %r12		# val <= 0?jle NoAdd3iaddq $1, %rax
NoAdd3:	andq %r13, %r13		# val <= 0?jle NoAdd4iaddq $1, %rax
NoAdd4:	mrmovq 32(%rdi), %r10	# read val from src...mrmovq 40(%rdi), %r11	# read val from src...mrmovq 48(%rdi), %r12	# read val from src...mrmovq 56(%rdi), %r13	# read val from src...rmmovq %r10, 32(%rsi)	# ...and store it to dstrmmovq %r11, 40(%rsi)	# ...and store it to dstrmmovq %r12, 48(%rsi)	# ...and store it to dstrmmovq %r13, 56(%rsi)	# ...and store it to dstandq %r10, %r10		# val <= 0?jle NoAdd5iaddq $1, %rax
NoAdd5:	andq %r11, %r11 	# val <= 0?jle NoAdd6iaddq $1, %rax
NoAdd6:	andq %r12, %r12		# val <= 0?jle NoAdd7iaddq $1, %rax
NoAdd7:	andq %r13, %r13 	# val <= 0?jle NoAdd8iaddq $1, %rax
NoAdd8:	iaddq $64, %rdiiaddq $64, %rsiandq %rdx, %rdxjg JudgeretJudge:	iaddq $-8, %rdxjge Unfold8iaddq $8, %rdx
Judge2:iaddq $-2, %rdxjge Unfold2iaddq $2, %rdxSingleLoop:mrmovq (%rdi), %r10	# read val from src...rmmovq %r10, (%rsi)	# ...and store it to dstandq %r10, %r10		# val <= 0?jle Doneiaddq $1, %raxretUnfold2:mrmovq (%rdi), %r10	# read val from src...mrmovq 8(%rdi), %r11	# read val from src...rmmovq %r10, (%rsi)	# ...and store it to dstrmmovq %r11, 8(%rsi)	# ...and store it to dstandq %r10, %r10		# val <= 0?jle Noadd1iaddq $1, %rax
Noadd1:	andq %r11, %r11 	# val <= 0?jle Noadd2iaddq $1, %raxNoadd2:	iaddq $16, %rdiiaddq $16, %rsiandq %rdx, %rdxjg Judge2

参考

CSAPP | Lab4-Architecture Lab 深入解析 - 知乎 (zhihu.com)

[读书笔记]CSAPP:ArchLab - 知乎 (zhihu.com)

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

斗地主登录界面(JAVA图形化界面)设置

1.实现代码 import CodeUtil.CodeUtil; import domain.User;import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList;public class LoginGame extends JFrame implements MouseListen…

高校毕业生就业管理系统(ssm)

登录界面 管理员界面 学生界面 企业的单位用户界面 1、系统说明 &#xff08;1&#xff09;spring、springmvc、mybatis、mysql、jsp &#xff08;2&#xff09;系统分为学生、管理员、企业用户三种角色 欢迎留言交流学习&#xff0c;qq: 978206256

kubesphere部署k8s-v1.23.10

功能&#xff1a; &#x1f578; 部署 Kubernetes 集群 &#x1f517; Kubernetes 多集群管理 &#x1f916; Kubernetes DevOps &#x1f50e; 云原生可观测性 &#x1f9e9; 基于 Istio 的微服务治理 &#x1f4bb; 应用商店 &#x1f4a1; Kubernetes 边缘节点管理 &#x1…

信创ARM架构QT应用开发环境搭建

Linux ARM架构QT应用开发环境搭建 前言交叉工具链Ubuntu上安装 32 位 ARM 交叉工具链Ubuntu上安装 64 位 ARM 交叉工具链 交叉编译 QT 库下载 QT 源码交叉编译 QT 源码 Qt Creator交叉编译配置配置 Qt Creator Kits创建一个测试项目 小结 前言 有没有碰到过这种情况&#xff1…

有向图的拓扑排序-BFS求解

题目 给定一个n个点m条边的有向图&#xff0c;图中可能存在重边和自环。 请输出任意一个该有向图的拓扑序列&#xff0c;如果拓扑序列不存在&#xff0c;则输出-1。 若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y)&#xff0c;x在A中都出现在y之前&#xff0c;则称…

Vue3开发环境搭建和工程结构(一)

一、NVM和Node.js安装 NVM 是 Node Version Manager&#xff08;Node 版本管理工具&#xff09;的缩写&#xff0c;是一个命令行工具&#xff0c;用于管理和切换到不同版本的 Node.js。 1、前往 nvm-windows 仓库&#xff0c;然后单击立即下载 2、下载最新版本 3 、按照安装向…

HarmonyOS远程真机调试方法

生成密钥库文件 打开DevEco Studio&#xff0c;点击菜单栏上的build&#xff0c; 填一些信息点击&#xff0c;没有key的话点击new一个新的key。 生成profile文件 AppGallery Connect (huawei.com) 进入该链接网站&#xff0c;点击用户与访问将刚生成的csr证书提交上去其中需…

机器学习系列5-特征组合、简化正则化

1.特征组合 1.1特征组合&#xff1a;编码非线性规律 我们做出如下假设&#xff1a;蓝点代表生病的树。橙色的点代表健康的树。 您可以绘制一条直线将生病的树与健康的树清晰地分开吗&#xff1f;不可以。这是一个非线性问题。您绘制的任何线条都无法很好地预测树的健康状况…

redis下载与安装教程(centos下)

文章目录 一&#xff0c;redis下载1.1上传到linux服务器上 二&#xff0c;redis安装2.1 安装依赖2.2 解压包2.3 编译并安装2.4 指定配置启动2.5 设置redis开机自启 一&#xff0c;redis下载 官网&#xff1a; https://redis.io1.1上传到linux服务器上 我用filezila上传到/us…

防御保护---防火墙的可靠性

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.防火墙可靠性概述 防火墙的防护功能基于状态检测的前提下会存在会话表&#xff1b;会话表存在老化时间&#xff0c;仅在流量触发后防火墙会刷新会话表&#xff0c;因此防火墙无法像路由器那样…

如何部署Linux AMH服务器管理面板并结合内网穿透远程访问

文章目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装Cpolar4. 配置AMH面板公网地址5. 远程访问AMH面板6. 固定AMH面板公网地址 AMH 是一款基于 Linux 系统的服务器管理面板&#xff0c;它提供了一系列的功能&#xff0c;包括网站管理、FTP 管理、数据库管理、DNS 管…

C++泛编程(4)

类模板高级&#xff08;1&#xff09; 1.类模板具体化部分具体化完全具体化 2.类模板与继承 1.类模板具体化 有了函数模板具体化的基础&#xff0c;学习类模板的具体化很简单。类模板具体化有两种方式&#xff0c;分别为部分具体化和完全具体化。假如有类模板&#xff1a; te…