前言

就目前hash算力而言,PC上的CPU和GPU是怎么也比不了专门的硬件的,所以本文只是出于学习的目的而写。

GPU编程概念简述

GPU编程,是将庞大的计算任务,分割成独立小任务后,交给GPU中动辄数

百上千甚至上万的处理单元,并行处理。比如要计算2000个 8*8 ,如果是cpu处理的话是要循

环2000次,但交给一个有2000个处理单元的GPU计算,每个处理单元计算一个8*8,则只需要一次即可全部计算完成。

关于Sha256原理

引用一篇文章,已把原理说的很明白了。

SHA256算法原理详解: https://blog.csdn.net/u011583927/article/details/80905740/

本文使用的sha256实现,是修改Bitcoin Core的sha256实现而来。

规则简述

1. sha256的规则是对要hash的数据体以512bit分割为一个块,并以前一个块为基础做64次逻辑计算。

2. 比特币挖矿是指对区块头做sha256 得到hash_1,然后再次对hash_1做sha256后得到hash_2

这个hash_2即是最终的区块hash,然后比对这个hash_2 如果<=全网难度,则挖矿成功。

实现思路

因只是用于比特币挖矿的hash(数据体长度固定),而不是通用的hash(数据体长度不固定只能循环处理)

所以可以将区块头数据hash的指令全部展开为顺序执行,然后交给每个GPU的处理单元

这样,假如GPU有2000个处理单元,那么交给GPU一轮计算就可得到2000个hash结果。

实现细节

流程:

1. CPU端, 第一次补位: 是将比特币区块头数据补齐,如下:

区块头640bit(80byte) + 补位384bit(48byte) = 1024bit(512bit*2) = 128byte

2. 上述补位后的128byte数据交给GPU的每个处理单元,处理单元内的流程如下:

1. 替换nonce值,如下:

nonce在比特币头数据第76byte处,长度4个byte,将其修改为新的nonce值。

2. 将128byte分割为两个512bit的块,并按顺序对每个块执行sha256的64个逻辑运算得到结果hash_1。

3. 将hash_1补位,如下:

hash_1 32byte(256bit) + 补位32byte = 512bit = 64byte

4. 再次对补位后的hash_1做sha256运算,得到结果hash_2,此hash_2即是最终block hash.

测试结果

2.5 GHz 四核Intel Core i7

16 GB 1600 MHz DDR3

Intel Iris Pro 1536 MB

测试hash次数 20,480,000 次

CPU 消耗时间: 115.809秒

GPU 消耗时间: 11.477 秒

以下是部分代码摘录,全部代码请参考 比特币GPU独立挖矿节点中的以下文件

btc_sha256_gpu.h

btc_sha256_gpu.cpp

btc_sha256_gpu.cl

CPU端补位代码

// 将blockheader的80byte数据补位到128byte

void BTC_SHA256_GPU::PadBlockHaderData(TBlockHeaderBytes& vBytes) {

// 128 = 80(block头数据) + 48(sha256补位数据)

uint8_t* buf = &vBytes[0];

// 将后48byte置0

memset(buf+80, 0, 48);

// 补位

*(buf+80) = 0x80; // 数据末尾补 1000 0000

uint8_t rawDataSize[8];

WriteBE64(rawDataSize, 80 << 3); // 写入big endian (<<3的是乘以8)

memcpy(buf + 120, rawDataSize, 8);

}

GPU端Kernel部分代码

inline void DoHash(uint32_t* s, uint8_t* data, uint8_t blocks, uint8_t* out) {

Reset(s);

T(s, data, blocks);

Finalize(s, out);

}

/**

*

* @param pIn 根据sha256补位规则好的block头信息数组

* @param pOut 双sha256后的hash结果数组

* @param nonceOffset nonce的起始点

*/

__kernel void BtcDoubleSHA256(__global uint8_t* pIn, __global uint8_t* pOut, unsigned int nonceOffset) {

/**

* 双Sha256 Hash

* 1. pIn内是已经按照sha256规则补位好的128byte的区块头数据

* 128byte=1024bit=区块头(80byte=640bit)+补位(384bit=48byte)

* 2. 修改pIn内区块头内的nonce数据

* 3. 对修改后的pIn做一次sha256 hash运算

* 4. 对上述运算后的32byte的hash结果按sha256规则再次进行补位到512bit(64byte)

* 5. 再次对补位后的64byte做第二次sha256 hash运算

* 6. 将第二次hash结果输出

*/

uint32_t _s[8]; // sha256初始因子

uint8_t hashResult[64];

// 当前 puid

int puId = get_global_id(0);

// 当前需要处理的数据从global拷贝到private内存中

// private内存的读写速度优于global

uint8_t data[IN_DATA_SIZE];

#pragma unroll

for(int i =0; i < IN_DATA_SIZE; ++i) {

data[i] = pIn[i];

}

// 将nonce写入block header数据内

uint32_t nonce = puId + nonceOffset;

memcpy(data + NONCE_OFFSET, &nonce, 4);

// 第一次计算hash(128byte)

memset(hashResult, 0, 64);

DoHash(_s, data, 2, hashResult);

// 第二次hash前的补位(64byte)

hashResult[32] = 0x80; // sha256补位分隔符号

uint8_t rawDataSize[8];

WriteBE64_EX(rawDataSize, 32 << 3); // 写入big endian (<<3的是乘以8)

memcpy(hashResult + 56, rawDataSize, 8);

// 第二次计算hash

DoHash(_s, hashResult, 1, hashResult);

// 将本workitem的双hash结果拷贝到输出buf中

uint64_t outDataOffset = puId * OUT_DATA_SIZE;

#pragma unroll

for(int i =0; i < OUT_DATA_SIZE; ++i) {

pOut[i + outDataOffset] = hashResult[i];

}

}

java gpu hash_比特币 GPU 挖矿 Sha256 Hash实现(OpenCL)相关推荐

  1. [源码解析] NVIDIA HugeCTR,GPU版本参数服务器--- (5) 嵌入式hash表

    [源码解析] NVIDIA HugeCTR,GPU版本参数服务器- (5) 嵌入式hash表 文章目录 [源码解析] NVIDIA HugeCTR,GPU版本参数服务器--- (5) 嵌入式hash表 ...

  2. 如何在Java中生成比特币钱包地址

    让我们通过学习比特币(Bitcoin)如何实施该技术的各个方面来工作,好吗?该技术包括以下几个方面: 比特币地址bitcoin address是用来发送和接收比特币的. 交易transaction是比 ...

  3. 讨论帖:比特币中的SHA256算法的实现与标准的SHA256算法实现是否相同?

    近日阅读了比特币源码中与哈希相关的部分,对于其中一些细节还是有不清晰的地方. 于是我写了一个小的测试demo:sha256_test,代码下载 分别测试了三个版本对于SHA-256算法的实现: Bit ...

  4. 分享下最近的Nvidia GPU 3060 laptop GPU、linzhi、Tesla算力曲线

    分享下最近的Nvidia GPU 3060 laptop GPU. 算力曲线, 单台笔记本实际算力40MHash,超频可以到48Mhash,我一般设置到46M Hash.风扇睡觉时放在同一个房间略微有 ...

  5. How to Avoid Branching on the GPU 如何在GPU避免分支

    在GPU避免分支的方法 Authored by Brandon Fogerty(XR Graphics Engineer at Unity Technologies.) with Additional ...

  6. TensorFlow指定使用GPU 多块gpu

    持续监控GPU使用情况命令: $ watch -n 10 nvidia-smi 1 一.指定使用某个显卡 如果机器中有多块GPU,tensorflow会默认吃掉所有能用的显存, 如果实验室多人公用一台 ...

  7. float gpu 加速_tensorflow - GPU 加速

    首先检测是否可用 GPU importtensorflow as tfprint('GPU', tf.test.is_gpu_available()) #GPU True tf.device Tens ...

  8. OpenCV之gpu 模块. 使用GPU加速的计算机视觉:GPU上的相似度检测(PNSR 和 SSIM)

    GPU上的相似度检测(PNSR 和 SSIM) 学习目标 在 OpenCV的视频输入和相似度测量 教程中我们已经学习了检测两幅图像相似度的两种方法:PSNR和SSIM.正如我们所看到的,执行这些算法需 ...

  9. eth显卡算力2020最新排行_最新三大主流币IPFS比特币ETH挖矿全网算力动态速递单周报(12.3更新)...

    关注公众号懒人学投资 本周行情观察: 今日比特币当前价格是  122688  元, 今日以太坊当前价格是   3854     元, 今日ipfs当前价格是       198     元, btc稳 ...

最新文章

  1. 只能在堆或只能在栈上分配内存的类
  2. Asp.Net 构架(HttpModule 介绍)
  3. 端口复用和半关闭补充
  4. 有些事情女孩子越早知道越容易幸福
  5. [转载] java常量池-字符串常量池、class常量池和运行时常量池
  6. 学习 | egg.js 中间件和插件
  7. C#.NET中数组、ArrayList和List三者的区别
  8. Java 集合源码详解
  9. [剪视频]Premiere快速从入门到实战
  10. 考勤系统 java_java中一个简单考勤系统
  11. 无线AP 传输、认证
  12. 佛祖保佑永无BUG 代码 (各种样式)
  13. 模拟扑克牌的洗牌发牌
  14. Aspose.Word企业案例:Charity Auction Organizer 使用 Aspose.Words 开发自定义邮件合并引擎
  15. R语言基于dcurves包绘制COX回归临床决策曲线
  16. 汽车前覆盖板高速碰撞实验
  17. 20221126测试赛解题报告
  18. 数据库实现电商管理系统
  19. 【flash】个人用基础操作笔记
  20. laravel 实战 总结

热门文章

  1. java中反复使用代码_Java代码复用规则
  2. bmp280c语言程序,51单片机读取BMP280 180 280气压值1602显示程序
  3. app令牌登录解决session超时重登陆的问题
  4. [转]WF事件驱动(1)
  5. 职教高中计算机专业知识,新课改背景下计算机专业教学(职教)三维目标设计初探...
  6. 总结一下最近面试经常被问到的问题(2019年4月)
  7. 2019-03-13
  8. 想看程序员的成长课这本书
  9. m40型工业机器人_从工业机器人编程及应用到数控机床的安装维修,一次都学习了...
  10. ArcGIS水文分析实战教程(3)DEM数据准备