AlexanderStandridge
理学硕士研究生
加洲学院北岭校区
CalvinHo
理学硕士研究生
加洲学院北岭校区calvin.
ShahnamMirzaei
助理院长
加洲学院北岭校区
RaminRoosta
院长
加洲学院北岭校区
将可编程逻辑与处理器子系统集成在单个元件中,开发出适应性强、经济适用的比特币矿机。
比特币是一种虚拟货币,在过去几年里渐渐流行开来。由此,比特币的跟随者通过采购或则“挖矿”比特币的方式,投入其部份资产来支持这些货币。挖矿是指使用计算机硬件为比特币网路执行物理估算的过程。提供服务的比特币矿工可以得到一笔酬金(目前是25比特币)以及任何内含的交易费用。因为网路酬金是根据所有矿工完成的估算量进行分配的,故挖矿的竞争异常激烈。
比特币挖矿开始是在CPU和GPU这样的低成本硬件上运行的一个软件进程。但随着比特币流行开来,挖矿过程发生了戏曲性转变。初期的矿工必须使用高帧率处理器能够实现令人满意的“哈希速率”,也就是挖矿速率。即使使用CPU/GPU挖矿效率非常低下,但其灵活度足以适应比特币合同的变化。近些年来,挖矿活动的重心渐渐转移到专用或半专用ASIC硬件上,以优化和实现高效“哈希速率”。转用这些硬件提升了挖矿效率,但其代价是增加了适应挖矿合同变化的灵活性。
ASIC是一种在特定应用中拿来高效执行个别特定任务的专用硬件。其实ASIC比特币矿机成本相对较低,且得到的“哈希速率”也相当优异,但其代价是增加了灵活性,无法适应合同的变化。
与ASIC相像,FPGA可也用作高效矿机系统,但是成本也相对较低。据悉,FPGA与ASIC相比灵活性更强,才能适应比特币合同的变化。目前的困局是须要设计出一款不借助PC主机或中继装置能够联接到比特币网路的完全高效且相当灵活的挖矿系统。我们团队使用赛灵思Zynq-7000AllProgrammableSoC顺利完成了这一任务。
总体思路
要设计出一个由可行的比特币节点和高效灵活的矿机等组成的完整挖矿系统,我们须要某种功能强悍的FPGA芯片,来同时满足灵活性和性能要求。除FPGA外,我们还须要使用处理引擎来提升效率。
在这个完整的片上系统(SoC)上,我们须要经优化的内核来运行包括网路维护和交易处理在内的所有要求的比特币任务。能满足所有那些条件的硬件就是坐落ZedBoard开发板上的Zynq-7020SoC。ZedBoard售价大概在300到400欧元,与同类产品相比linux系统官网,价钱相当实惠(参见)。
Zynq-7020SoC芯片集成有两个ARM®Cortex™-A9处理器和85,000个Artix®-7FPGA逻辑单元。ZedBoard开发板还外置有512MBDDR3储存器,才能让我们更快速地运行SoC设计。最后,ZedBoard还提供一个用于海量储存的SD卡槽,以易于我们把整个更新后的比特币程序储存在SD卡上。
我们使用ZedBoard实现了我们的SoC比特币矿机。它由主机、中继器、驱动程序和矿机组成。我们使用原始比特币顾客端的非图形化界面作为主机,与比特币网路进行互动。中继器使用驱动程序从主机向矿机传递工作。
简单来说,可以把比特币挖矿进程归结为一个SHA-256进程和一个比较器的组合。SHA-256进程负责对块头信息进行两次处理,之后将其与比特币网的扩充目标难度做比较。
挖矿内核的深入
我们依照用日本商务部SHA-256的尺寸,采用Vivado®HLS(高层次综合)开始开发挖矿内核。使用VivadoHLS的快速行为测试功能,我们很快完成了几个原型挖矿内核的布局,从简单的单进程系统到复杂的多进程系统都有。但在探究挖矿内核的详尽结构前,先了解一下SHA-256进程的基本知识是大有益处的。
SHA-256经过64次移位、相加和异或运算迭代,将64字节数据生成32字节哈希值。在这个运算过程中,用8个4字节寄存器保存每一轮迭代的结果。当这一过程完成后,将四个寄存器联接上去,生成哈希值。倘若输入数据不足63字节,就将其弥补为63字节,第64个字节用于储存输入数据的厚度。更为常见的情况是输入数据的厚度小于63字节。
在这些情况下,数据弥补为64的最接近倍数,并将最后一个字节保留用于储存数据宽度。每一个64字节数据块使用上一个数据块的输出(亦称为中间态)作为下一个数据块的基础,依次运行SHA-256进程。
使用VivadoHLS,SHA-256进程就是个简单的“for”循环设计:用一个阵列保持每次迭代所需的常数,用另一个阵列保持后续迭代使用的临时值比特币挖矿程序 linux,用8个变量保持每次迭代的结果,而且定义逻辑运算。如图2所示。
简单的来说,可以把比特币挖矿过程归结为一个SHA-256进程和一个比较器的组合。SHA-256进程负责对块头信息进行两次处理,之后将其与比特币网的扩充目标难度做比较,如图3A所示。这个简单的概念在硬件中施行上去却很复杂,由于第一版的比特币块头为80字节长。这就意味着初始路径须要运行SHA-256进程两次,后续路径仅须要运行一次,如图3B所示。这些定义两个单独的SHA-256模块的双路径,会让情况复杂化,由于我们须要让SHA-256模块尽量通用,以节约开发时间,实现重复借助。这些对SHA-256模块的通常性要求决定了我们使用的输入和输出,可将其设定为32字节初始值、64字节数据和32字节的哈希值。为此,在隔离SHA-256进程的内核侧后,我们可以随便布局这种输入。
我们开发的三个原型中的第一个原型使用单个SHA-256进程模块。从一开始我们就晓得这个内核是三个中最慢的,由于没有使用流水线。但我们想瞧瞧能实现的最小SHA-256进程是多大。
第二个原型外置三个串联上去的单独SHA-256进程模块,如图3C所示。这些配置在第一个进程处理数据头信息中的第一个64个字节时容许静态输入。第二个进程负责处理数据头中剩余的16个字节以及加上弥补数据所需的48字节。第三个进程负责处理从前两个进程得到的哈希值结果。这三个单独的进程简化了控制逻辑,以便使用简单流水线。
第三个也是最后一个原型使用两个SHA-256进程模块,并在比特币挖矿社区使用的比特币数据头信息和挖矿进程中充分借助专用补丁的作用。只有在更改模块使头64字节发生变化时,就会布局这些数据头信息。这意味着一旦头64个字节处理完毕,就可以保存输出数据(中间态),只处理数据头中的最后16个字节,就可以大幅度地提升哈希速率(参见图3D)。
比较器属于主要组件,经适当设计才能明显提高性能。解是一个哈希值,其数值大于比特币系统定义的32字节扩充目标难度。这就意味着必须比较形成的每一个哈希值,等待看是否可以找到解。因为扩充目标难度搭配有一个专用补丁,所以不管难度怎样,头四个字节会始终为0。随着网路难度的减小,前导零的数目也在增多。在编撰本程序时,扩充目标难度的头13个字节都是零。为此,不仅要将整个哈希值与目标难度做比较,我们还须要检测前多少个字节是零。假如它们是零,我们就将哈希值与目标难度做比较。假如它们不是零,我们须要将此哈希值遗弃,从新再来。
在清楚现有各类原型的结果后,我们最终选用比特币开源社区专为赛灵思FPGA开发的第三个内核。
ISE的开发
比特币挖矿是在0和232-1之间找到可作为解的数值的赛事。因而,实际上只有两种方式可以改善挖矿内核的性能:推动处理或分而治之。我们使用Spartan®-3和Spartan-6开发板测试了一系列不同的频度、流水线方法和并行化方式。
我们先用Spartan-3E开发板开始频度测试。但很快就发觉超过50MHz就无能为力。因此,我们只得用Spartan-6来完成频度测试。
我们在Spartan-6开发板上测试了50、100和150MHz三种不同频度,得到了可预测的结果,分别得到了0.8MHps、1.6MHps和2.4MHps。在并行化和流水线测试中,我们还尝试了75MHz和125MHz,不过这两种频度只是使矿机适配Spartan-6所做的妥协。
我们从开源社区选择挖矿内核的诱因之一是:它的设计理念是用深度变量来控制流水线级数。深度是介于0和6之间的一个指数值,用于控制以2的幂计的VHDL“generate”命令的执行次数,即20次到26次。我们进行初始频度测试的深度是0,即每位进程只执行一轮。
在Spartan-3e上,我们测试了深度0和1,直到运行到发生时序约束问题。深度0在50MHz下可得到大概0.8MHps,深度1可得到大概1.6MHps。
在Spartan-6上,在运行到发生时序约束问题之前,我们实现的深度可以达到3。运行在50MHz,深度为0和1时,Spartan-6与Spartan3得到的结果一样。这时我们注意到一个有趣的趋势。频度翻番与减小流水线深度的疗效相同。上限由可用的路由资源决定,峰值平均数大概为3.8MHps,如图4所示。
SHA-256进程模块须要完成10次不同的32位相乘。在本设计中,我们企图在一个时钟周期内完成全部相乘。为减短最长路径,我们企图将加法器链细分为一系列阶段。但这样做会让整个核的控制逻辑发生明显改变,须要彻底重新编撰。我们舍弃了这种更改,以节约时间和精力。
我们最后测试的性能改进方式是并行化。只需稍作更改,就可以让SHA-256组数弄成2倍和4倍。每组由两个SHA-256进程模块组成。对组数提升2倍的SHA-256而言,这些调整可有效地把组数减半;对组数提升4倍的SHA-256,就是四分之一。为让那些额外的SHA进程才能在Spartan-6上运行比特币挖矿程序 linux,我们不得不减少系统频度。四组SHA-256进程模块在75MHz运行,两组在125MHz运行。哈希速率的改善情况未能记录。我们可以轻易地看见单个SHA-256组的哈希速率,不过多组SHA-256构成的挖矿内核找到解的速率比蕴涵的哈希速率更快。
使用EDK
在FPGA测试以后,下一步是把挖矿内核联接到ZynqSoC的AXI4总线。赛灵思嵌入式开发套件(EDK)预先加载有专为ZynqSoC设计的配置实用工具,以便我们轻松地配置每一个方面。默认情况下该系统会启用512MBDDR3、以太网、USB和SD插口,这是比特币SoC所需的全部配置。
两个Cortex-A9处理器采用AXI4插口,而非往年软核系统使用的PLB系统。所有的外设均经AXI4插口联接到处理器,如图5所示。
EDK订制外设向导针对AXI4插口的不同变种提供收据代码,且用作挖矿内核AXI插口的开发基础。为简单起见,我们使用AXI4-Lite插口为挖矿内核提供简单的读写功能。在理想的情况下,开发人员会想要使用标准的AXI4插口,以发挥先进插口控制功能的作用,如数据突发。
为达到简单的目的,我们使用三个储存器映射寄存器来处理挖矿内核的I/O。第一个寄存器负责向矿机馈送主机数据包。该寄存器记录通过的数据量,到第11个字通过后自我加锁。加锁会在找到解后手动解锁。假如有必要,也可通过状态寄存器自动解锁。
我们将第二个寄存器用作状态寄存器,给特定的位做上标记,用于代表挖矿内核在运行过程中所处的不同状态。鉴于我们的设计简单,我们只使用三个标记,即加载标记、运行标记和发觉解标记。当挖矿内核收到11个字时即触发加载标记,如前所述,当我们向其写入时,即消除。开始/运行标记在启动挖矿内核时设置,在找到解时被挖矿内核清理。最终的寄存器为输出寄存器,用于加载找到的解。
在加入这个新组件前,我们对AXI4-Lite插口开发的每一个阶段进行了测试。我们还使用赛灵思软件开发套件中的准系统,测试了AXI4-Lite插口。测试有两个目的:首先,确认挖矿内核的AXI4-Lite插口是否正常工作;其次,确保挖矿内核是否以正确的字节储存顺序格式接收数据。
为了在不牺牲适应性的前提下改进我们目前的设计,我们打算添加更多联接到主比特币节点的挖矿内核。添加更多挖矿内核后可明显提高性能,推动整体哈希速率。
嵌入式LINUX
完成挖矿内核与处理器的联接后,我们转向软件开发工作。理想的考虑是使用Linux内核建立我们自己的固件,以实现最高性能。为简化开发工作,我们安装完整的Linux版本。我们使用的是Xillybus开发的Xillinux,属于Ubuntu的衍生版本,用于快速完成嵌入式系统开发。
我们的首要任务是为Cortex-A9构架编译编译Bitcoind。我们使用原始的开源比特币软件,以保证与比特币网路的兼容性。
测试Bitcoin是件简单的事情。我们先运行后台程序,等待下载规模可观的数据库链,之后使用行命令,启动Bitcoind内建的CPU挖矿软件。
对于Linux驱动程序,必须实现一部份专用功能,将其链接到Linux内核,就能实现正确运行。当加载有特定初始化功能的驱动程序运行时,让系统为与硬件互动做好打算。在此项功能中,我们首先确认挖矿内核打算链接的储存器地址可以使用,之后将该地址保留上去。与准系统不同,Linux使用虚拟储存器地址方案,即在我们可以使用保留的地址之前,我们必须先为挖矿内核申请地址重映射。内核会通过重映射,为我们提供一个虚拟地址,供我们随即与挖矿内核寄存器通讯。
既然如今我们可以使用这个硬件,初始化功能随即可对挖矿内核进行一个简单的测试,来确认内核工作正常。假如运行正常,就登记内核寄存器的主元件号和次元件号,用于在用户程序中辨识该元件。每一项功能都有一个计数器,退出功能就是初始化功能的计数器。用此功能时,我们撤消在初始化过程中完成的一切操作,具体而言就是释放驱动程序使用的主元件号和次元件号,之后释放映射的虚拟地址。
我们首先从中继程序调用挖矿内核时,打开功能开始运行。我们在这儿所做的全部工作是确认初始化过程中功能自检是否成功。假如自检失败,我们就给出系统出错信息,失败退出。当元件从中继程序中释放时,即调用关掉功能。但因为我们只在打开功能中检测自检结果,故关掉功能中没有哪些可做的。读取功能负责查看数据缓存,判定用户正在读取哪一个端口,之后从挖矿内核获取数据,并将其传回。写入功能负责判定用户正在写入的寄存器,之后将数据传递给挖矿内核。
我们系统的最后一个组件是一个精巧的中继程序,用于通过驱动程序将工作从Bitcoind传递给挖矿内核,并会送结果。理所其实的,这个中继程序须要查看Bitcoind是否在运行中,挖矿内核是否打算就绪,是否工作正常。因为中继程序在大多数时间里处于待机状态,我们打算设计一个统计编制子系统,用于挖矿数据并将数据组织在一个日志文件中。在理想情况下,我们将使用Web主机界面供配置、显示统计结果和显示元件状态使用。
完整高效的挖矿系统
我们用ZebBoard开发板上的赛灵思Zynq-7000AllProgrammableSoC开发出高效完整的比特币挖矿系统。该开发板才能灵活地适应比特币合同的变化,同时提供具备SoC功能的高性能FPGA解决方案。为了在不牺牲适应性的前提下改进我们目前的设计,我们打算添加更多联接到主比特币节点的挖矿内核。添加更多挖矿内核后可明显地提高性能linux论坛,推动整体哈希速率。
另一项进一步优化该设计的改进是使用专用固件。我们目前的设计运行的是UbuntuLinux12.04版。这个版本有大量何必要的进程和SSH等比特币程序同时运行。在比特币程序运行的同时运行那些进程是对开发板资源的浪费。在将来的版本中,我们将取消这种进程,只运行专为比特币任务订制的我们自己的固件。