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 portion
	xorq %rax,%rax		# count = 0;
	andq %rdx,%rdx		# len <= 0?
	jg Loop		        # if so, goto Done:
	ret
	
Loop:	mrmovq (%rdi), %r10	# read val from src...
	rmmovq %r10, (%rsi)	# ...and store it to dst
	andq %r10, %r10		# val <= 0?
	jle NoAdd1
	iaddq $1, %rax

NoAdd1:	
	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 portion
	xorq %rax,%rax		    # count = 0;
	andq %rdx, %rdx
	jg Judge
	ret
	
Judge:	
	iaddq $-8, %rdx
	jge Loop6
	iaddq $8, %rdx

Loop1:
	mrmovq (%rdi), %r10	    # read val from src...
	rmmovq %r10, (%rsi)	    # ...and store it to dst
	andq %r10, %r10		    # val <= 0?
	jle NoAdd
	iaddq $1, %rax
NoAdd:
	iaddq $8, %rdi
	iaddq $8, %rsi
	iaddq $-1, %rdx
	jg Loop1		
	ret
	
Loop6:	
	mrmovq (%rdi), %r10	    # read val from src...
	rmmovq %r10, (%rsi)	    # ...and store it to dst
	andq %r10, %r10		    # val <= 0?
	jle NoAdd1
	iaddq $1, %rax
NoAdd1:	
	mrmovq 8(%rdi), %r10	# read val from src...
	rmmovq %r10, 8(%rsi)	# ...and store it to dst
	andq %r10, %r10 	    # val <= 0?
	jle NoAdd2
	iaddq $1, %rax
NoAdd2:	
	mrmovq 16(%rdi), %r10	# read val from src...
	rmmovq %r10, 16(%rsi)	# ...and store it to dst
	andq %r10, %r10		    # val <= 0?
	jle NoAdd3
	iaddq $1, %rax
NoAdd3:	
	mrmovq 24(%rdi), %r10	# read val from src...
	rmmovq %r10, 24(%rsi)	# ...and store it to dst
	andq %r10, %r10		    # val <= 0?
	jle NoAdd4
	iaddq $1, %rax
NoAdd4:	
	mrmovq 32(%rdi), %r10	# read val from src...
	rmmovq %r10, 32(%rsi)	# ...and store it to dst
	andq %r10, %r10		    # val <= 0?
	jle NoAdd5
	iaddq $1, %rax
NoAdd5:	
	mrmovq 40(%rdi), %r10	# read val from src...
	rmmovq %r10, 40(%rsi)	# ...and store it to dst
	andq %r10, %r10		    # val <= 0?
	jle NoAdd6
	iaddq $1, %rax
NoAdd6:	
	mrmovq 48(%rdi), %r10	# read val from src...
	rmmovq %r10, 48(%rsi)	# ...and store it to dst
	andq %r10, %r10		    # val <= 0?
	jle NoAdd7
	iaddq $1, %rax
NoAdd7:	
	mrmovq 56(%rdi), %r10	# read val from src...
	rmmovq %r10, 56(%rsi)	# ...and store it to dst
	andq %r10, %r10		    # val <= 0?
	jle NoAdd8
	iaddq $1, %rax
NoAdd8:	
	iaddq $64, %rdi
	iaddq $64, %rsi
	andq %rdx, %rdx
	jg Judge		        
	
	

8x1展开+2x1展开+消除气泡,CPE=8.10 
# You can modify this portion
	#xorq %rax,%rax		# count = 0;
	andq %rdx, %rdx
	jg Judge
	ret
	
Unfold8:	
	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 dst
	rmmovq %r11, 8(%rsi)	# ...and store it to dst
	rmmovq %r12, 16(%rsi)	# ...and store it to dst
	rmmovq %r13, 24(%rsi)	# ...and store it to dst
	andq %r10, %r10		# val <= 0?
	jle NoAdd1
	iaddq $1, %rax
NoAdd1:	
	andq %r11, %r11 	# val <= 0?
	jle NoAdd2
	iaddq $1, %rax
NoAdd2:	
	andq %r12, %r12		# val <= 0?
	jle NoAdd3
	iaddq $1, %rax
NoAdd3:	
	andq %r13, %r13		# val <= 0?
	jle NoAdd4
	iaddq $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 dst
	rmmovq %r11, 40(%rsi)	# ...and store it to dst
	rmmovq %r12, 48(%rsi)	# ...and store it to dst
	rmmovq %r13, 56(%rsi)	# ...and store it to dst
	
	andq %r10, %r10		# val <= 0?
	jle NoAdd5
	iaddq $1, %rax
NoAdd5:	
	andq %r11, %r11 	# val <= 0?
	jle NoAdd6
	iaddq $1, %rax
NoAdd6:	
	andq %r12, %r12		# val <= 0?
	jle NoAdd7
	iaddq $1, %rax
NoAdd7:	
	andq %r13, %r13 	# val <= 0?
	jle NoAdd8
	iaddq $1, %rax
NoAdd8:	
	iaddq $64, %rdi
	iaddq $64, %rsi
	andq %rdx, %rdx
	jg Judge
	ret
	
Judge:	
	iaddq $-8, %rdx
	jge Unfold8
	iaddq $8, %rdx
Judge2:
	iaddq $-2, %rdx
	jge Unfold2
	iaddq $2, %rdx
	
SingleLoop:
	mrmovq (%rdi), %r10	# read val from src...
	rmmovq %r10, (%rsi)	# ...and store it to dst
	andq %r10, %r10		# val <= 0?
	jle Done
	iaddq $1, %rax
	ret
	
Unfold2:
	mrmovq (%rdi), %r10	# read val from src...
	mrmovq 8(%rdi), %r11	# read val from src...
	rmmovq %r10, (%rsi)	# ...and store it to dst
	rmmovq %r11, 8(%rsi)	# ...and store it to dst
	andq %r10, %r10		# val <= 0?
	jle Noadd1
	iaddq $1, %rax
Noadd1:	
	andq %r11, %r11 	# val <= 0?
	jle Noadd2
	iaddq $1, %rax

Noadd2:	
	iaddq $16, %rdi
	iaddq $16, %rsi
	andq %rdx, %rdx
	jg Judge2
	

参考

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

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

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

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

相关文章

中小学信息学奥赛CSP-J认证 CCF非专业级别软件能力认证-入门组初赛模拟题一解析(选择题)

CSP-J入门组初赛模拟题一&#xff08;选择题&#xff09; 1、以下与电子邮件无关的网络协议是 A、SMTP B、POP3 C、MIME D、FTP 答案&#xff1a;D 考点分析&#xff1a;主要考查小朋友们网络相关知识的储备&#xff0c;FTP是文件传输协议和电子邮件无关&#xff0c;所以…

vscode debug无法直接查看eigen变量的问题(解决方法)

主要是给gdb添加一个Eigen相关的printer即可, 网上其他教程都搞太复杂了, 我整理成了一个仓库, 把仓库克隆下来直接运行 ./setup.sh脚本即可配置好 git clone gitgithub.com:fandesfyf/EigenGdb.git cd EigenGdb ./setup.sh 然后在vscode中重新debug即可。 效果 …

2.2-学成在线内容管理之课程分类查询+新增课程

文章目录 内容管理模块4 课程分类查询4.1 需求分析4.2 接口定义4.3 接口开发4.3.1 树型表查询4.3.2 开发Mapper 4.4 接口测试4.4.1 接口层代码完善4.4.2 测试接口 5 新增课程5.1 需求分析5.1.1 业务流程4.1.2 数据模型 5.2 接口定义5.3 接口开发5.3.1 保存课程基本信息5.3.2 保…

深度学习系列55:深度学习加速技术概述

总体有两个方向&#xff1a;模型优化 / 框架优化 1. 模型优化 1.1 量化 最常见的量化方法为线性量化&#xff0c;权重从float32量化为int8&#xff0c;将输入数据映射在[-128,127]的范围内。在 nvdia gpu&#xff0c;x86、arm 和 部分 AI 芯片平台上&#xff0c;均支持 8bit…

嵌入式系统中的电磁兼容和电磁干扰问题如何解决?

嵌入式系统在现代科技领域中发挥着越来越重要的作用&#xff0c;无论是在智能手机、汽车、医疗设备还是工业控制系统中&#xff0c;嵌入式系统都扮演着关键的角色。然而&#xff0c;随着嵌入式系统功能的不断扩展和集成度的增加&#xff0c;电磁兼容性(EMC)和电磁干扰(EMI)问题…

SpringBoot集成axis发布WebService服务

文章目录 1、使用maven-web项目生成server-config.wsdd文件1.1、新建maven-web项目1.1.1、新建项目1.1.2、添加依赖 1.2、编写服务接口和实现类1.2.1、OrderService接口1.2.2、OrderServiceImpl实现类 1.3、配置deploy.wsdd文件deploy.wsdd文件 1.4、配置tomcat1.4.1、配置tomc…

交友系统---让陌生人变成熟悉人的过程。APP小程序H5三端源码交付,支持二开。

随着社交网络的发展和普及&#xff0c;人们之间的社交模式正在发生着深刻的变革。传统的线下交友方式已经逐渐被线上交友取而代之。而同城交友正是这一趋势的产物&#xff0c;它利用移动互联网的便利性&#xff0c;将同城内的人们连接在一起&#xff0c;打破了时空的限制&#…

【node】Node.js的常用内置模块:

文章目录 一、os模块&#xff1a;【1】常用的OS模块方法包括&#xff1a;【2】案例&#xff1a; 二、path模块&#xff1a;【1】常用的path模块方法包括&#xff1a;【2】案例&#xff1a; 三、url模块&#xff1a;【1】常用的url模块方法包括&#xff1a;【2】案例&#xff1a…

LeetCode--代码详解 2.两数相加

2.两数相加 题目 难度&#xff1a;中等 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数…

数字孪生:智慧城市的核心技术与发展

一、引言 随着城市化进程的加速&#xff0c;智慧城市的概念和实践逐渐成为全球关注的焦点。智慧城市利用先进的信息通信技术&#xff0c;提升城市治理水平&#xff0c;改善市民的生活质量。而数字孪生作为智慧城市的核心技术&#xff0c;为城市管理、规划、应急响应等方面提供…

【数据分享】1929-2023年全球站点的逐日平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;说到常用的降水数据&#xff0c;最详细的降水数据是具体到气象监测站点的降水数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全…

[Angular 基础] - 数据绑定(databinding)

[Angular 基础] - 数据绑定(databinding) 上篇笔记&#xff0c;关于 Angular 的渲染过程及组件的创建&简单学习&#xff1a;[Angular 基础] - Angular 渲染过程 & 组件的创建 Angular 之中的 databinding 是一个相对而言更加复杂&#xff0c;以及我个人觉得相对而言比…

《MySQL》超详细笔记

目录 基本知识 主流数据库 数据库基本概念 MySQL启动 数据库基本命令 数据库 启动数据库 显示数据库 创建数据库 删除数据库 使用数据库 查询当前数据库信息 显示数据库中的表 导入数据库脚本 表 查看表的结构 查看创建某个表的SQL语句 数据库的查询命令 查询…

设计模式学习笔记(一):基本概念;UML

文章目录 参考面向对象的设计原则创建型模式结构型模式行为型模式 UML视图图&#xff08;Diagram&#xff09;模型元素(Model Element)通用机制类之间的关系关联关系复杂&#xff01;&#xff01;聚合关系组合关系 依赖关系泛化关系接口与实现关系 参考 https://github.com/fa…

OpenCV/C++:点线面相关计算(二)

接续&#xff0c;继续更新 OpenCV/C:点线面相关计算_线面相交的点 代码计算-CSDN博客文章浏览阅读1.6k次&#xff0c;点赞2次&#xff0c;收藏12次。OpenCV处理点线面的常用操作_线面相交的点 代码计算https://blog.csdn.net/cd_yourheart/article/details/125626239 目录 1、…

Micro micro controller一览

https://www.microchip.com.cn/&#xff0c; Microchip中文网站 https://www.microchip.com.cn/newcommunity/index.php?mSearch&adosearch&moduleDownload&keyworddsPIC33&p3 Microcontrollers and microProcessors dsPIC33 Digital Signal Controllers (D…

假期刷题打卡--Day24

1、MT1198阶乘差 求1!-2!-3!-…-n! 格式 输入格式&#xff1a; 输入为整型 输出格式&#xff1a; 输出为整型 样例 1 输入&#xff1a; 5输出&#xff1a; -151 分析过程 看到这个题目的时候&#xff0c;感觉这个题目出现的没有必要&#xff0c;就和前面阶乘和一样的…

MySQL数据库练习【一】

MySQL数据库练习【一】 一、建库建表-数据准备二、习题2.1. 查询部门编号为30的部门的员工详细信息2.2.查询从事clerk工作的员工的编号、姓名以及其部门号2.3.查询奖金多于基本工资的员工的信息、查询奖金小于基本工资的员工的信息2.4.查询奖金多于基本工资60%的员工的信息2.5.…

transformers重要组件(模型与分词器)

1、模型&#xff1a; from transformers import AutoModelcheckpoint "distilbert-base-uncased-finetuned-sst-2-english" model AutoModel.from_pretrained(checkpoint) 除了像之前使用 AutoModel 根据 checkpoint 自动加载模型以外&#xff0c;我们也可以直接…

算法学习——LeetCode力扣哈希表篇2

算法学习——LeetCode力扣哈希表篇2 454. 四数相加 II 454. 四数相加 II - 力扣&#xff08;LeetCode&#xff09; 描述 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 …