流水账(CPU设计实战)——lab3

Lab3 Rewrite V1.0

版本控制

版本描述
V0
V1.0相对V0变化: 修改了文件名,各阶段以_stage结尾(因为if是关键词,所以module名不能叫if,遂改为if_stage,为了统一命名,将所有module后缀加上_stage) 删除了imm_sign信号(默认对立即数进行有符号数扩展) 由于对sw指令进行了重新理解:无论如何都是需要将rt_data传递给EXE阶段,故将部分译码逻辑进行后移至EXE阶段,避免id_to_exe_data总线过于庞大 将ins_shmat剔除出id_to_exe_data,因为imm包括ins_shamt 对信号进行重命名(例如在ID阶段有个信号叫rf_we,最终要传递给WB阶段,那么在EXE阶段,该信号叫作exe_rf_we,同理mem_rf_we,wb_rf_we),不然都叫rf_we,Debug的时候太痛苦了。

Top顶层

接口信号

MYCPU_TOP.v(TOP

名称宽度方向描述
时钟与复位
clk1I时钟信号,来自clk_pll的输出时钟
resetn1I复位信号,低电平同步复位
取指端访存接口
inst_sram_en1O指令RAM使能信号,高电平有效
inst_sram_wen4O指令RAM字节写使能信号,高电平有效
inst_sram_addr32O指令RMA读写地址,字节寻址
inst_sram_wdata32O指令RAM写数据
inst_sram_rdata32I指令RAM读数据
数据端访存接口
data_sram_en1O数据RAM使能信号,高电平有效
data_sram_wen4O数据RAM字节写使能信号,高电平有效
data_sram_addr32O数据RAM读写地址,字节寻址
data_sram_wdata32O数据RAM写数据
data_sram_rdata32I数据RAM读数据
debug信号,供验证平台使用
debug_wb_pc32O写回级(多周期最后一级)的PC,需要myCPU里将PC一路传递到写回级
debug_wb_rf_wen4O写回级写寄存器堆(regfiles)的写使能,为字节使能,如果myCPU写regfiles为单字节写使能,则将写使能扩展成4位即可
debug_wb_rf_wnum5O写回级写regfiles的目的寄存器号
debug_wb_rf_wdata32O写回级写regfiles的写数据

接口时序

略(MIPS经典五级流水线)

代码结构

MYCPU_TOP.v

|____IF.v

|____ID.v

|____RF.v(2个读端口,1个写端口)

|____EXE.v

|____ALU.v

|____MEM.v

|____WB.v

|____MYCPU.h

DATA_RAM.v

IF.v(修改为IF_STAGE,因为会与关键词if冲突)

接口信号

名称宽度方向描述
时钟与复位
clk1I时钟信号,来自clk_pll的输出时钟
resetn1I复位信号,低电平同步复位
与TOP
inst_sram_en1ORAM使能信号,高电平有效
inst_sram_wen4ORAM字节写使能信号,高电平有效
inst_sram_addr32ORMA读写地址,字节寻址
inst_sram_wdata32ORAM写数据
inst_sram_rdata32IRAM读数据
与ID
id_to_if_allowin1Ipipe allowin
if_to_id_vld1Opipe valid
if_to_id_data64Opipe data(instruction 32-bits, pc 32-bits)
jump_bus33Ibranch instructions(enable 1bit,address 32-bits)

接口时序

在这里插入图片描述
在这里插入图片描述

ID.v

接口信号

名称宽度方向描述
时钟与复位
clk1I时钟信号,来自clk_pll的输出时钟
resetn1I复位信号,低电平同步复位
与IF
id_to_if_allowin1Opipe allowin
if_to_id_vld1Ipipe valid
if_to_id_data64Ipipe data(instruction 32-bits, pc 32-bits)
jump_bus33Obranch instructions(enable 1bit,address 32-bits)
与EXE
exe_to_id_allowin1Ipipe allowin
id_to_exe_vld1Opipe valid
id_to_exe_data135O{ins_R:1, ins_I:1, imm:16, alu_op:13, mem_rd:1, mem_we:1, rf_we:1, rf_dst_addr:5, data_1:32, data_2:32, pc:32}
与WB
wb_to_rf_bus38I{rf_we:1, rf_addr:5, rf_data:32}

接口信号(RF.v)

名称宽度方向描述
时钟与复位
clk1I时钟信号,来自clk_pll的输出时钟
与ID内部信号
rf_r_addr15IRF读地址1
rf_r_data132ORF读数据1
rf_r_addr25IRF读地址2
rf_r_data232ORF读数据2
rf_wen11IRF写使能1
rf_w_addr15IRF写地址1
rf_w_data132ORF写数据1

接口时序

在这里插入图片描述

电路设计

在这里插入图片描述

图3-4-1 译码电路分组(注:黄线少画了两条)

根据附录——MIPS指令。由于跳转指令不传递给EXE阶段,直接传递给IF阶段,且为纯组合逻辑输出,有可能成为关键路径,故对跳转指令单独处理。除了跳转指令外,涉及加法(减法归为加法)的指令如图3-4-1所示,即ins_addu、ins_addiu、ins_subu、ins_lw、ins_sw。

对于图3-4-1的拼接运算,可以当作移位运算执行。

EXE.v

接口信号

名称宽度方向描述
时钟与复位
clk1I时钟信号,来自clk_pll的输出时钟
resetn1I复位信号,低电平同步复位
与TOP(外接的DATA_RAM)
data_sram_en1O数据RAM使能信号,高电平有效
data_sram_wen4O数据RAM字节写使能信号,高电平有效(4个比特,应该代表32 = 4 bytes)
data_sram_addr32O数据RAM读写地址,字节寻址
data_sram_wdata32O数据RAM写数据
与ID
exe_to_id_allowin1Opipe allowin
id_to_exe_vld1Ipipe valid
id_to_exe_data135I{ins_R:1, ins_I:1, imm:16, alu_op:13, mem_rd:1, mem_we:1, rf_we:1, rf_dst_addr:5, data_1:32, data_2:32, pc:32}
与MEM
mem_to_id_allowin1Ipipe allowin
exe_to_mem_vld1Opipe valid
exe_to_mem_data71O{mem_rd:1, rf_we:1, rf_dst_addr:5, pc:32(其实可以删掉pc,这里是debug显示用的,可以叫debug_pc), exe_result:32

接口信号(ALU.v)

暂时不需要时钟和复位,纯组合逻辑

名称宽度方向描述
时钟与复位
clk1I时钟信号,来自clk_pll的输出时钟
resetn1I复位信号,低电平同步复位
与ID内部信号
alu_shamt6IALU移位(R-指令的shamt部分)
alu_op13IALU操作(加、减、乘除、位运算)
alu_din132IALU输入1
alu_din232IALU输入2
alu_out32OALU输出

接口时序

在这里插入图片描述
在这里插入图片描述

MEM.v

接口信号

名称宽度方向描述
时钟与复位
clk1I时钟信号,来自clk_pll的输出时钟
resetn1I复位信号,低电平同步复位
与TOP(外接的DATA_RAM)
data_sram_rdata32I数据RAM读数据
与EXE
mem_to_exe_allowin1Opipe allowin
exe_to_mem_vld1Ipipe valid
exe_to_mem_data71I{mem_rd:1, rf_we:1, rf_dst_addr:5, pc:32(其实可以删掉pc,这里是debug显示用的,可以叫debug_pc), exe_result:32}
与WB
wb_to_mem_allowin1Ipipe allowin
mem_to_wb_vld1Opipe valid
mem_to_wb_data70O{ rf_we:1, rf_dst_addr:5, mem_result:32, pc:32(其实可以删掉pc,这里是debug显示用的,可以叫debug_pc)}

WB.v

接口信号

名称宽度方向描述
时钟与复位
clk1I时钟信号,来自clk_pll的输出时钟
resetn1I复位信号,低电平同步复位
与TOP
debug_wb_pc32O写回级(多周期最后一级)的PC,需要myCPU里将PC一路传递到写回级(与原书保持一致)
debug_wb_rf_wen4O写回级写寄存器堆(regfiles)的写使能,为字节使能,如果myCPU写regfiles为单字节写使能,则将写使能扩展成4位即可(与原书保持一致)
debug_wb_rf_wnum5O写回级写regfiles的目的寄存器号(与原书保持一致)
debug_wb_rf_wdata32O写回级写regfiles的写数据(与原书保持一致)
与MEM
wb_to_mem_allowin1Opipe allowin
mem_to_wb_vld1Ipipe valid
mem_to_wb_data70I{ rf_we:1, rf_dst_addr:5, mem_result:32, pc:32(其实可以删掉pc,这里是debug显示用的,可以叫debug_pc)}
与ID
wb_to_rf_bus38O{rf_we:1, rf_addr:5, rf_data:32}

接口时序

在这里插入图片描述

附录——参考

  1. 参考:处理机流水线------经典五段流水线-CSDN博客

附录——原书指令

指令sel_nextpcinst_ram_weninst_ram_wensel_alu_src1sel_alu_src2alu_opdata_ram_endata_ram_wenrf_wesel_rf_dstsel_rf_res
ADDU0001100010010000000000010010010
ADDIU0001100010100000000000010010100
SUBU0001100010010000000000100010010
LW0001100010100000000000011010101
SW0001100010100000000000011100000
BEQ0010100000000000000000000000000
BNE0010100000000000000000000000000
JAL0100100101000000000000010011000
JR1000100000000000000000000000000
SLT0001100010010000000001000010010
SLTU0001100010010000000010000010010
SLL0001101000010001000000000010010
SRL0001101000010010000000000010010
SRA0001101000010100000000000010010
LUI0001100000101000000000000010100
AND0001100010010000000100000010010
OR0001100010010000010000000010010
XOR0001100010010000100000000010010
NOR0001100010010000001000000010010

附录——Debug

PC复位问题

在这里插入图片描述

PC的跳转有误,直接看IF_STAGE.v

修改代码为:

在这里插入图片描述

RegFile的零寄存器问题

在这里插入图片描述

修改如下:

在这里插入图片描述

RF数据高阻

在这里插入图片描述

发现数据有错,应当为63:32

在这里插入图片描述

跳转指令的PC值

跳转指令的PC,本人使用的都是ID阶段的pc,经过vivado调试,发现有误,隧改为如下,即使用IF阶段的pc:

在这里插入图片描述

lui译码错误

在ID阶段,lui指令译码错误,具体如下:

assign ins_lui = op_ext[6’h15] & rs_ext[5’h00];//错误

改为如下:

assign ins_lui = op_ext[6’h0f] & rs_ext[5’h00];

addiu执行错误

经排查,发现在ID阶段,忘了声明rs_data和rt_data这两个变量,导致被默认为1 bit(实际都是32 bit的变量)

addiu执行错误

(影响Debug了)

经排查,发现rs数据读取为高阻,向前追溯,发现是写寄存器的时候,写入的是高阻,最终发现在WB阶段的,rf_we始终为高,更改如下:

assign rf_we = wb_data[69] ;

assign debug_wb_rf_wen = {4{rf_we}} ;

assign wb_to_rf_bus[37] = rf_we & wb_vld;

改为:

assign rf_we = wb_data[69] & wb_vld;

assign debug_wb_rf_wen = {4{rf_we}} ;

assign wb_to_rf_bus[37] = rf_we ;

然而还是有错,遂向前回溯,发现RF.v中的rf_group声明有误:

reg [31:0] rf_group [4:0];

改为:

reg [31:0] rf_group [31:0];

lw错误

发现电路设计本身就有问题,原因为:从CSDN上的一个MIPS指令集设计的电路,但是该CSDN上的内容是错的!!!

电路设计错误:发现rf_we漏掉了ins_lw

在这里插入图片描述

更改如下:

assign rf_we = ins_addu

|ins_addiu

|ins_subu

|ins_lw

|ins_jal

|ins_slt xxxxxx ;

subu错误

在这里插入图片描述

assign alu_din2_two_cmpl[31] = 1’b1;

assign alu_din2_two_cmpl[30:0] = (~alu_din2) + 1’b1;

上面两句,修改为下:

assign alu_din2_two_cmpl[31:0] = (~alu_din2) + 1’b1;

在MIPS指令中有subu和sub两种指令,(lab3只要求实现subu,不要求实现sub指令)而在代码中本人将subu简写为sub是不合适的,已全部修改为subu

slt报错

在这里插入图片描述

原始代码:

assign result_slt = ($signed(alu_din1) < $signed(alu_din2)) ? 32’h1: 32’h0;

学习了下原书上的源码,发现可以将比较运算合并至减法运算,于是修改了slt(同时也修改了sltu)如下:

assign add_din2 = (alu_subu | alu_slt | alu_sltu) ? alu_din2_two_cmpl
alu_din2;

另外,我发现单独进行求补码运算,可能会浪费加法器,不利于vivado优化,遂修改

在这里插入图片描述

修改为:

在这里插入图片描述

nor报错

assign result_nor = ~result_xor ;

更改为:

assign result_nor = ~ result_or ;

srl报错

在这里插入图片描述

发现ID阶段的译码错误:

assign ins_srl = op_ext[6’h00] & sa_ext[5’h00] & fun_ext[6’h06];

更改为:

assign ins_srl = op_ext[6’h00] & rs_ext[5’h00] & fun_ext[6’h02];

sra报错

在这里插入图片描述

assign result_sra = alu_din2 >>> alu_shamt ;

更改为:

assign result_sra = $signed(alu_din2) >>> alu_shamt ;

sw/lw报错

lw报错,经排查是因为sw命令有误

本人设计的时候没有认真分析sw指令,导致EXE阶段的sram_wdata数据有误。

具体地讲,由于本人设计阶段欠缺,误认为加法结果给到sram_wdata(实际上加法结果是给sram_addr),导致出错。

由于欠思考导致总线也需要更改,需要将rt_data从ID阶段传递给exe阶段,因为sw指令执行中需要将rt_data赋给sram_wdata。

bne出错

在这里插入图片描述

又是码错了

assign jump_bne = (rt_equ_rs == 1’b0) & ins_beq ;

更改为:

assign jump_bne = (rt_equ_rs == 1’b0) & ins_bne ;

完结

还有一些小bug没有记录,终于pass了,完结。

在这里插入图片描述

后记

  1. 原书是将regfile.v当作ID_stage的一个子模块,WB_stage写回时,也是通过ID_stage的顶层将信号传递到regfile模块。本设计将regfile.v置于与ID、WB的同一hierarchy

  2. 原书将跳转指令(如JAL)的译码放在ID_stage模块中(没有问题,因为译码就是在ID_stage阶段),并以组合逻辑的形式传递给IF_stage(必须用组合逻辑,否则会影响流水)。本设计将跳转指令放在IF模块中,避免组合逻辑穿越模块边界。(还是不要合并,因为R、I、J型指令均含有跳转指令,合并至IF模块,会增加大量的额外译码逻辑。)

  3. 原书的译码方式值得学习:

    在这里插入图片描述

    在这里插入图片描述

    若是按我之前的写法,大概率会写成如下形式:

    always@(*)begin

    case(xxxx)

    endcase

    end

    always-case的形式容易写错,而且不够清晰。使用原书的写法,避免写成:

    inst_addu = (op == 6’h0 ) & (func == 6’h21) & (sa == 5’h00);

  • 小括号太多,看着就乱
  • 等号也影响纠错
  • 原书将0写成00,格式上是对齐的,更舒服
  • 另外我猜测将判断逻辑写成generate—endgenerate的形式,也更容易让编译器进行优化
  1. 在自己设计译码的时候,本人遇到一个问题,译码到什么程度才算“译码”。是译码出R\I\J型指令(每种类型用1bit标志位表示),还是译码至具体的加减乘除?

    我的思想:EXE除了负责寄存一些必要数据外(比如WB需要的数据),其核心执行内容应当只有:加、减、乘、除、移位、与、或、非、异或。也就是说,ID阶段负责输入的数据给准备好级EXE。然后我就在想Regfile怎么搞,因为Regfile读是不需要周期的(即本周期给出地址,本周就可以得到数据),但是WB写Regfile的时候,如果同时读Regfile的同一地址,怎么办呢?这个读写冲突应当放在Regfile中处理吗?

    另一方面,EXE的执行时,输入可以是寄存器(比如and指令),也可以是pc(比如跳转指令)。当输入是寄存器时,需要读Regfile,当输入是pc时,不需要读Regfile,将Regfile置于与ID、EXE同一hierarchy,意味着需要在EXE阶段判断输入是pc还是来自Regfile,这样增加了复杂性。(我现在理解了原书为什么要把Regfile当作ID的子模块,还是有道理的)

  2. 原lab3中的ID_stage.v中的ds_to_es_bus是136bits,但是在EXE阶段还存在少量的译码,我认为译码这种东西应当在ID阶段全部完成,不应当在EXE阶段还进行译码。

  3. 译码逻辑我写的是:assign {ins_op, ins_rs, ins_rt, ins_rd, ins_sa, ins_fun} = ins;

    原书代码给的是:

    assign ins_op = ins[31:26];

    assign ins_rs = ins[25:21];

    assign ins_rt = ins[20:16];

    assign ins_rd = ins[15:11];

    assign ins_sa = ins[10:6] ;

    assign ins_fun = ins[5:0] ;

    assign ins_index = ins[25:0] ;

    assign ins_imm = ins[15:0] ;

感觉还是书上写的比较易读,隧写成书上的这种形式

  1. 实例化,我写的是:

decoder_6_64 U_decoder_6_64(

.din ( ins ),

.dout( ins_ext )

);

原书上写的是:

decoder_6_64 U_decoder_6_64(.din ( ins ),.dout( ins_ext ) );

感觉还是差不多,我还是按我自己的写

  1. 在译码过程中对于5bits转32bits,和6bits转64bits。本人可以理解opcode和function需要转换成64bits、32bits,但是不明白rs、rt、rd、sa为何还需要转换。我现在是怀疑,后续指令会扩展,然后译码的时候将rt、rd、sa也加进去,可以确保指令译码的唯一性。

  2. 我原本想将ID阶段中的译码中的rf_dst_addr按下图进行Coding:

    在这里插入图片描述

    但是看了原书的代码后,认为,没默认ins_R选项即可,只需要判断其他写寄存器地址,遂改为如下:

    assign rf_dst_addr = ins_jal ? 5’d31 : ins_I ? ins_rt : ins_rd ;

同理,也对data_2的生成进行了类似的修改。

  1. 原书源码中每个阶段的pc值叫作fs_pc、ds_pc等,而我写的代码中都叫作pc,导致使用vivado调试时,都叫作pc不好定位
  2. 在跑通了全程后(共两周,包括Debug两天),感觉自己的Coding水平还是不如原书,而且控制信号和数据通路结构层次不好,级与级之间的bus编码(信号的放置位置等)也不够完美,数据的命名相同不利于debug(比如都叫pc,分不清是if的pc,还是exe的pc)。数据的耦合严重,尤其是ID与EXE阶段,两个阶段的信号耦合过于严重。除此之外还有资源上的复用也有所欠缺。还有一点就是出现了许多Coding的问题,比如wire信号忘记声明就使用,bne却使用了beq的信号。最后一点就是9.14节的sw/lw报错问题,这个bug,本人解决了一个晚上加一个上午,因为在设计阶段,是按照CSDN上的一篇博客上给出的MIPS指令设计的,所以一直没意识到博客本身就有问题,这种先入为主的指令加上本人设计的代码结构在sw/lw指令上耦合严重,导致后来阅读龙芯给的PDF时也没意识的问题,最后阅读了lab3原书上的源码才发现问题。

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

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

相关文章

杭州威雅学校:在学业与生活平衡中找到更好的自己

进入威雅杭州校园&#xff0c; 沿湖边小道步行约5分钟&#xff0c; 四栋寄宿学院与教学区隔湖相望&#xff0c; 威雅人更喜欢叫他们&#xff1a; 「Cavell」&「Dove」 「Elgar」&「Hawking」 提起「寄宿制」&#xff0c;人们本能地会把它和「住校」划等号。 这种…

css中实现背景方格

background: rgba(241,241,241,0.1); background-image:linear-gradient(90deg, rgba(241,243,244,1) 10%, transparent 0),linear-gradient(rgba()241,243,244,1 10%, transparent 0); background-size: 10px 10px; 表现出来的样子就是这个样子

96.网络游戏逆向分析与漏洞攻防-ui界面的设计-角色管理功能的界面设计

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

机器之心 | 清华接手,YOLOv10问世:性能大幅提升,登上GitHub热榜

本文来源公众号“机器之心”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;清华接手&#xff0c;YOLOv10问世&#xff1a;性能大幅提升&#xff0c;登上GitHub热榜 相同性能情况下&#xff0c;延迟减少 46%&#xff0c;参数减少 2…

超市进销存|基于SprinBoot+vue的超市进销存系统(源码+数据库+文档)

超市进销存系统 目录 基于SprinBootvue的超市进销存系统 一、前言 二、系统设计 三、系统功能设计 1 登录注册 2 管理员功能模块 3员工功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#x…

多系统集成的项目周期为何普遍较长?

在现代企业的运营中&#xff0c;各种信息系统的集成已成为提升效率和竞争力的关键。然而&#xff0c;当工厂的ERP系统需要与MES、SRM、WMS、CRM等其他系统集成时&#xff0c;项目周期往往长达一年以上&#xff0c;这不仅耗费时间、人力和财力&#xff0c;还可能影响企业的正常运…

开发者的福音:免去搭建服务,让你的应用开发变得像吃蛋糕一样简单!

传统应用开发的"噩梦" 想象一下&#xff0c;你正在准备一场盛大的晚宴&#xff0c;但必须从零开始建造厨房、种植食材、甚至学习烹饪技巧。这就是传统应用开发的现状——你不仅要设计数据库、编写API接口&#xff0c;还要处理对象存储、实时数据库、云数据库等一系列…

常见的数据分析方法

1.周期性分析法 一个指标的观察时间拉长,看它是否有周期变化规律。周期性分析常见的有两者:自然周期和生命周期。自然周期,指业务指标会随着时间自然变化,如节假日用户/业绩出现下滑、产品销售额随季节变动等;生命周期,譬如“商品生命周期”、“APP生命周期”、“用户生…

vue3 <script setup> 语法糖时间组件

<template><div><p>当前时间Current Time: {{ currentTime }}</p></div> </template><script setup> import { ref, onBeforeUnmount, onMounted } from vueconst currentTime ref()let interval // 声明 interval 变量const getTo…

反射、类加载、静态代理,jdk动态代理,cglib代理

一、 反射 反射是在程序运行状态下&#xff0c;动态获取类的结构&#xff08;属性&#xff0c;构造器&#xff0c;方法&#xff0c;注解&#xff09;&#xff0c;动态的创建类对象然后调用类中的属性方法。反射的起源Class&#xff0c;Class中包含类反射要使用的API 获取Class的…

java项目级云MES源码(制造执行系统) springboot + vue-element-plus-admin生产制造业MES系统源码

java项目级云MES源码&#xff08;制造执行系统) springboot vue-element-plus-admin生产制造业MES系统源码 MES系统通过信息传递对从订单下达到产品完成的整个生产过程进行优化管理。当工厂发生实时事件时&#xff0c;MES制造执行系统功能的发挥重点体现在及时做出反应、报告&…

期权成交量太小卖不出去怎么办?

今天期权懂带你了解期权成交量太小卖不出去怎么办&#xff1f;在期权交易的世界里&#xff0c;成交量是一个至关重要的指标&#xff0c;它犹如行情的晴雨表&#xff0c;反映着市场的活跃程度。 期权成交量太小卖不出去怎么办&#xff1f; 耐心等待&#xff1a;如果期权合约的流…

图计算与ID-Mapping

目录 一、图计算&#xff1a; 图计算起源&#xff1a; 图计算特点&#xff1a; 图计算的应用&#xff1a; Spark GraphX图处理库 ID-Mapping 二、总结&#xff1a; 一、图计算&#xff1a; 图&#xff08;Graph&#xff09;是用于表示对象之间关联关系的一种抽象数据结构…

Java面试八股之对threadLocal是怎么理解的

对threadLocal是怎么理解的 概念与特点&#xff1a;ThreadLocal是Java提供的一个类&#xff0c;它允许你创建线程局部变量。每个线程都拥有自己的ThreadLocal变量副本&#xff0c;彼此之间互不影响&#xff0c;实现了变量在线程间的隔离。这意味着&#xff0c;即使多个线程使用…

深入理解MySQL索引下推优化

在MySQL中&#xff0c;索引的使用对于查询性能至关重要。然而&#xff0c;即使有合适的索引&#xff0c;有时查询性能仍然不尽如人意。索引下推&#xff08;Index Condition Pushdown&#xff0c;ICP&#xff09;是一项能够进一步优化查询性能的技术。本文将详细讲解索引下推的…

【Linux】权限的理解之权限掩码(umask)

目录 前言 一、利用八进制数值表示文件或目录的权限属性 二、系统默认的权限掩码和权限掩码的作用原理 三、分析权限掩码改变文件或目录的权限属性 前言 权限掩码是由4个数字组合而成的&#xff0c;默认的第一位数字是0&#xff1b;后三位数字分别由八进制位数字组成。权限…

【JVM精通之路】垃圾回收-三色标记算法

首先预期你已经基本了解垃圾回收的相关知识&#xff0c;包括新生代垃圾回收器&#xff0c;老年代垃圾回收器&#xff0c;以及他们的算法&#xff0c;可达性分析等等。 先想象一个场景 最开始黑色节点是GC-Roots的根节点&#xff0c;这些对象有这样的特点因此被选为垃圾回收的根…

Transformers x SwanLab:可视化NLP模型训练

HuggingFace 的 Transformers 是目前最流行的深度学习训框架之一&#xff08;100k Star&#xff09;&#xff0c;现在主流的大语言模型&#xff08;LLaMa系列、Qwen系列、ChatGLM系列等&#xff09;、自然语言处理模型&#xff08;Bert系列&#xff09;等&#xff0c;都在使用T…

Mowgli用于配对多组学整合

对同一组细胞的多个分子层进行分析逐渐流行。越来越需要能够联合分析这些数据的多视图学习方法。Mowgli是一种支持配对多组学数据的整合方法。值得注意的是&#xff0c;Mowgli将非负矩阵分解和最优传输相结合&#xff0c;同时提高了非负矩阵分解的聚类性能和可解释性。作者将Mo…

android studion 一直编译失败

无外网&#xff0c;无法下载对应的库导致编译失败 配置代理 1.修改镜像源 资源路径 为国内镜像 如下为国美腾讯软件镜像 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-8.6-bin.zip 2.构建仓储失败 无法下载。 添加国内仓储如下位置&#xff0c;重新…