挖矿、难度与激励
从出块与难度读起,再深入算力、成本和矿池。
按议题整理 · 中文阅读 · 76 条发言。英文及完整讨论可回到对应档案查看。
多久能挖到一个区块
14 条
把它当成每天产出多少区块的倒置柱状图挺有意思。目标是每天 144 个区块。
如果有人做一个页面(类似 http://www.alloscomp.com/bitcoin/calculator.php 那…
如果有人做一个页面(类似 http://www.alloscomp.com/bitcoin/calculator.php 那个好用的计算器),预测下一次难度调整会调到多少,那就太好了。
预计难度调整倍数 =
blocks_since_last_adjustment / 2016
------------------------------------
time_since_last_adjustment / 14_days
举例来说,如果只用了 3.5 天而不是 7 天就走完了到下次调整的一半路程,我们预计难度会翻倍:
(1008/2016) / (3.5/14) = 0.5/0.25 = 2.0
另外,它还可以显示下次调整预计发生的时间,以及上次调整是什么时候、调了多少。
新难度系数 244.213223092
新难度系数 244.213223092
+35%
我已经更新了首帖。
日期,难度系数,变化百分比
2009 1.00
30/12/2009 1.18 +18%
11/01/2010 1.31 +11%
25/01/2010 1.34 +2%
04/02/2010 1.82 +36%
14/02/2010 2.53 +39%
24/02/2010 3.78 +49%
08/03/2010 4.53 +20%
21/03/2010 4.57 +9%
01/04/2010 6.09 +33%
12/04/2010 7.82 +28%
21/04/2010 11.46 +47%
04/05/2010 12.85 +12%
19/05/2010 11.85 -8%
29/05/2010 16.62 +40%
11/06/2010 17.38 +5%
24/06/2010 19.41 +12%
06/07/2010 23.50 +21%
13/07/2010 45.38 +93%
16/07/2010 181.54 +300%
27/07/2010 244.21 +35%
图漂亮!加个移动平均让它平滑一点就更好了。
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
图漂亮!加个移动平均让它平滑一点就更好了。
http://nullvoid.org/bitcoin/statistix.php 显示过去 24 小时有 212 个区块,即每小时 8.8 个。
很多生意都是这样。对汽车销售员来说,下一位顾客什么时候进门?
很多生意都是这样。对汽车销售员来说,下一位顾客什么时候进门?
关于楼主的问题:这是个好功能,但问题是怎么措辞才不会让人以为过了那个时间就一定有结果?「它说 7 天,我等了一个多星期什么都没拿到!」即使标明是估计值或平均值,人们还是会那么想。说明文字不能长到一整句话,除非我们另找个地方放,但放哪儿呢?大家出出主意?
几分钟前难度又翻了两番,181.54 了。现在生成一个通常要花大约一周。
几分钟前刚调整到 181.54。现在拿到一个区块的典型时间大约是一周。
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
几分钟前刚调整到 181.54。现在拿到一个区块的典型时间大约是一周。
难度既能上调也能下调。
网络现在应该接近每小时生成 6 个区块。
目前的工作量证明难度是 45.38。(见 http://www.alloscomp.com/bitcoin/calculat…
目前的工作量证明难度是 45.38。(见 http://www.alloscomp.com/bitcoin/calculator.php)
几个小时后又要上调了。距上次上调才 3、4 天,所以我预计会按上限 4 倍调,或者非常接近上限。那就会到 181.54。
两次调整的目标间隔是 14 天,14/3.5 天 = 4.0 倍上调。
难度一两天前刚翻倍,而且本来就是随机的,你可能会遇到长得惊人的空窗期。
这是一个常见的困惑点。不存在"完成了区块求解的 1%"这回事。你不会朝解出它取得进展。算了 24 小时之后,你解出它的概率与…
公式基于生成 2016 个区块所花的时间。难度乘以 14/(实际天数)。比如这次用了 9.4 天,计算就是 14/9.4 =…
公式基于生成 2016 个区块所花的时间。难度乘以 14/(实际天数)。比如这次用了 9.4 天,计算就是 14/9.4 = 1.49。之前的难度 2.53 * 1.49 = 3.78,上涨 49%。
我不知道你说的"接受更容易的难度"是什么意思。
自动调整就在今天早些时候发生了。
自动调整就在今天早些时候发生了。
24/02/2010 0000000043b3e500000000000000000000000000000000000000000000000000
24/02/2010 3.78 +49%
我更新了首帖。
只是运气不好的一阵连败而已。在我看来节奏很稳。
只是运气不好的一阵连败而已。在我看来节奏很稳。
竞争要到下一次自动难度调整才会起作用,而我们还没到下一次。
调整每 2016 个区块一次。要计算距下一次的进度,用区块总数除以 2016。小数部分就是本轮已经完成的进度。
我的粗略估算:42032 区块/2016 = 20.85,即走完了 85%。距下一次还有约 1.5 天。那距上次只有约 10 天,目标是 14 天,所以 14/10 = 1.4,难度上升 40% 左右。
昨天难度又是一次大幅跃升:从 1.82 倍到 2.53 倍,10 天里涨了 39%。间隔之所以是 10 天而非 14 天,是…
14/02/2010 0000000065465700000000000000000000000000000000000000000000000000
2009 1.00
30/12/2009 1.18 +18%
11/01/2010 1.31 +11%
25/01/2010 1.34 +2%
04/02/2010 1.82 +36%
14/02/2010 2.53 +39%
昨天难度又是一次大幅跃升:从 1.82 倍到 2.53 倍,10 天里涨了 39%。间隔之所以是 10 天而非 14 天,是因为有更多节点加入,用更少时间就生成了 2016 个区块。
2009 年 12 月 30 日,我们完成了第一次工作量证明难度的自动调整。
2009 年 12 月 30 日,我们完成了第一次工作量证明难度的自动调整。
最小难度是 32 个零位,所以哪怕只有一个人运行节点,难度也不会低于它。去年大部分时间,我们都在最小值以下徘徊。12 月 30 日,我们突破了它,算法随即上调了难度。此后,每次调整,难度都在上升。
2 月 4 日的调整,把它从去年的 1.34 倍提到 1.82 倍。这意味着,同样多的工作,只能生成 55% 的比特币。
难度按全网总算力成比例调整。节点数翻倍,难度也会翻倍,总产出就会回到目标速率。
给技术型读者:工作量证明难度可以在 debug.log 里搜 "target:" 看到。它是一个 256 位无符号十六进制数,SHA-256 值必须小于它才能成功生成区块。它每 2016 个区块调整一次,典型是两周。那时 debug.log 会打印 "GetNextWorkRequired RETARGET"。
minimum 00000000ffff0000000000000000000000000000000000000000000000000000
30/12/2009 00000000d86a0000000000000000000000000000000000000000000000000000
11/01/2010 00000000c4280000000000000000000000000000000000000000000000000000
25/01/2010 00000000be710000000000000000000000000000000000000000000000000000
04/02/2010 000000008cc30000000000000000000000000000000000000000000000000000
14/02/2010 0000000065465700000000000000000000000000000000000000000000000000
24/02/2010 0000000043b3e500000000000000000000000000000000000000000000000000
08/03/2010 00000000387f6f00000000000000000000000000000000000000000000000000
21/03/2010 0000000038137500000000000000000000000000000000000000000000000000
01/04/2010 000000002a111500000000000000000000000000000000000000000000000000
12/04/2010 0000000020bca700000000000000000000000000000000000000000000000000
21/04/2010 0000000016546f00000000000000000000000000000000000000000000000000
04/05/2010 0000000013ec5300000000000000000000000000000000000000000000000000
19/05/2010 00000000159c2400000000000000000000000000000000000000000000000000
29/05/2010 000000000f675c00000000000000000000000000000000000000000000000000
11/06/2010 000000000eba6400000000000000000000000000000000000000000000000000
24/06/2010 000000000d314200000000000000000000000000000000000000000000000000
06/07/2010 000000000ae49300000000000000000000000000000000000000000000000000
13/07/2010 0000000005a3f400000000000000000000000000000000000000000000000000
16/07/2010 000000000168fd00000000000000000000000000000000000000000000000000
27/07/2010 00000000010c5a00000000000000000000000000000000000000000000000000
05/08/2010 0000000000ba1800000000000000000000000000000000000000000000000000
15/08/2010 0000000000800e00000000000000000000000000000000000000000000000000
26/08/2010 0000000000692000000000000000000000000000000000000000000000000000
date, difficulty factor, % change
2009 1.00
30/12/2009 1.18 +18%
11/01/2010 1.31 +11%
25/01/2010 1.34 +2%
04/02/2010 1.82 +36%
14/02/2010 2.53 +39%
24/02/2010 3.78 +49%
08/03/2010 4.53 +20%
21/03/2010 4.57 +9%
01/04/2010 6.09 +33%
12/04/2010 7.82 +28%
21/04/2010 11.46 +47%
04/05/2010 12.85 +12%
19/05/2010 11.85 -8%
29/05/2010 16.62 +40%
11/06/2010 17.38 +5%
24/06/2010 19.41 +12%
06/07/2010 23.50 +21%
13/07/2010 45.38 +93%
16/07/2010 181.54 +300%
27/07/2010 244.21 +35%
05/08/2010 352.17 +44%
15/08/2010 511.77 +45%
26/08/2010 623.39 +22%
奖励、成熟期与激励
6 条
如果只让一个人去打包区块,那可能要花好几天。哦,你是说给每个节点发一个不同变体、把手续费写成给他们的?
没错,难度调整就是为了让网络整体保持平均每小时 6 个区块。你的区块成熟时间将始终在 20 小时左右。
没错,难度调整就是为了让网络整体保持平均每小时 6 个区块。你的区块成熟时间将始终在 20 小时左右。
最近这次调整让我们又回到了接近每小时 6 个区块。
有个网站可以看到区块之间的间隔时间,从区块 68545 起,大约是每 10 分钟一个区块:
对,大约 20 小时。(120 个确认 / 每小时 6 个区块 = 20 小时)这就是你能花掉它之前的正常时长。远在此之前你…
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
对,大约 20 小时。(120 个确认 / 每小时 6 个区块 = 20 小时)这就是你能花掉它之前的正常时长。远在此之前你就知道自己中奖了。
这个前提是错的。向正在计算的区块添加更多交易不会拖慢你的生成速度。生成时扫描哈希,只对区块头做哈希,区块头是固定大小。区块头…
尝试挖出区块时,以及成功挖出区块的那一刻,保持网络连接非常重要。
尝试挖出区块时,以及成功挖出区块的那一刻,保持网络连接非常重要。
1) 挖矿期间(状态栏显示 "Generating",CPU 正在寻找工作量证明时),你必须持续连接网络,以便收到最新区块。如果你的区块没有接在最新区块之后,它可能不会被接受。
2) 成功生成区块后,区块会立即广播到网络。其他节点必须收到它并接着它继续构建,它才会被接受为最新区块。
可以把它想象成大家合作接一条链。你要加上新的一环,必须先找到链条当前的末端。如果你找到最后一环后离开一小时,回来才把自己打造的链环接到一小时前的末端,别人可能已经接上了好几环。他们不会采用你这条已经从中间分叉出去的链。
区块生成后,要等待后续 120 个区块,以便在允许花费前,完全确认这个区块属于主链。在此期间,你的节点不会对这个区块做什么,只是在等待其他区块接到它后面。这段时间不必保持在线。
谢谢,我以前没见过。它的介绍看起来做得很好。以前还有一个已经运行很久的服务,会把哈希发布到 Usenet。这个没有用 Use…
引用的来信Dustin D. Trammell来源 ↗我正在读你的论文。在时间戳服务器那一节,你提到了报纸和 Usenet,所以我想,如果你还没见过这个,可能会感兴趣:
谢谢,我以前没见过。它的介绍看起来做得很好。以前还有一个已经运行很久的服务,会把哈希发布到 Usenet。这个没有用 Usenet,让我有点意外,不过如今要取得自动向 Usenet 发帖的权限,确实有些困难。如果他们能让一家杂志或报纸刊登自己的哈希,那么就更容易在法庭上实现他们的目的。比特币和所有时间戳服务器都具有同一种基本功能:定期把内容收集到区块里,再通过哈希运算把区块串成链。
引用的来信Dustin D. Trammell来源 ↗顺便说一下,我还在一台工作站上运行着 alpha 版代码。到目前为止,出现了两条“已生成”消息,但它们的“收入”栏都是 0.00,余额也没有变化。这是因为币要有效,就必须达到规定的年龄或成熟期吗?
对,收入栏在成熟之前一直是 0.00,成熟后就会变为 50.00。你觉得,如果成熟之前把收入栏留空,会不会更清楚?我应该在交易详情里(双击交易时显示)加一些文字,解释它是怎么运作的。(可以双击一行查看详情,这一点明显吗?)
如果还没升级,一定要升级到 v0.1.3。这个版本确实让运行稳定了下来。
Satoshi
挖矿成本与耗电
4 条
挖矿活动会逐渐集中到这些地方:
挖矿活动会逐渐集中到这些地方:
1) 成本最低或不用付费的地方
2) 出于理念、愿意贡献算力的人那里
3) 想直接获得一些比特币、不愿费事去交易购买的人那里
确实存在正当且无需额外成本的情况。凡是用电取暖的地方,挖矿基本不会增加额外成本,因为电脑产生的热量可以抵消一部分电暖器耗电。很多小公寓为了方便,本来就使用电暖。
取暖油有多贵?油价这么高,如果取暖油真的比电更贵,那么挖矿的净成本甚至可能是负数。
还有孩子把挖矿电费记在父母账上、员工让雇主承担电费,以及使用僵尸网络等情况。
第 3 种情况适用于小额需求。如果你只需要一点零钱来完成偶尔的微支付,专门去交易所兑换并不划算。我认为,这是它相比法定货币的一个优势:与其让货币发行收益全都归一个大型机构,不如把它拆成方便使用的小额资金,分给真正需要凑一点零钱的人。
如果你需要给家里取暖,你计算机的热量就没有浪费。如果你住的地方用电取暖,那你计算机的热量就不是浪费。用计算机发热取暖,成本是…
如果你需要给家里取暖,你计算机的热量就没有浪费。如果你住的地方用电取暖,那你计算机的热量就不是浪费。用计算机发热取暖,成本是一样的。
如果你有比电更便宜的取暖方式,那浪费只是两者的差价而已。
如果是夏天、你开着空调,那就是两倍。
Bitcoin 挖矿最终应该会集中到成本最低的地方。也许是寒冷地区用电取暖的地方,那里基本上等于免费。
这和黄金与挖金子的情形一样。挖金的边际成本总是倾向于贴近金价。挖金是浪费,但这种浪费远小于让黄金作为交换媒介可用所带来的效用…
这和黄金与挖金子的情形一样。挖金的边际成本总是倾向于贴近金价。挖金是浪费,但这种浪费远小于让黄金作为交换媒介可用所带来的效用。
我认为 Bitcoin 也会是同样的情形。Bitcoin 使交换成为可能所带来的效用,将远超其所耗电费。因此,没有 Bitcoin 才是净浪费。
其他参与者原话gridecon原帖 ↗总的来说,我也不认同「币生成的巨大计算负担是现行系统的必要代价」这种说法。据我理解,货币创造从根本上是以*时间*计量的——如果那才是根本控制变量,那为什么每个人还需要在给定时间段内「掷尽可能多的骰子」?币所有权和交易的「证明链」并不依赖比特币的生成方式。
每个节点对网络的影响力与其 CPU 算力成正比。向网络证明你有多少 CPU 算力的唯一办法,就是实际使用它。
如果还有别的什么东西,人人的持有量都有限、又能用来实现一人一票,那我想不出来。IP 地址……比 CPU 容易大量获取得多。
我想在某些时间点测量 CPU 算力也许是可能的。比如,CPU 算力挑战只在每 10 分钟里平均运行 1 分钟。你仍然可以在给定时间点证明你的总算力,而不必一直运行。不过我不确定这怎么能实现。一个当时不在场的节点,没有办法知道过去的链是否确实是按每轮间隔 9 分钟的工作周期生成的,而不是靠连续运算生成的。
工作量证明有个很好的性质:它可以通过不可信的中介转发。我们不必依赖消息传递链条上各个环节的可信度。是谁向你提供最长链并不重要,工作量证明自己会说话。
难度刚变成原来的 4 倍,所以现在你的成本是 0.02 美元/BTC。
处理器、显卡与挖矿提速
46 条
你应该试试 sha256.cpp 中 tcatm 的 4 路 SSE2 SHA 实现。它作为 C 文件编译没问题,只需把 s…
你应该试试 sha256.cpp 中 tcatm 的 4 路 SSE2 SHA 实现。它作为 C 文件编译没问题,只需把 sha256.cpp 改名为 sha256.c。我在 Windows 上简单测试时让它跑通了,但与 Bitcoin 链接时不行。作为 C 程序的一部分而不是 C++,成功的机会可能更大。
目前它只在 Linux 构建中启用,因此如果你让它跑通了,能让 Windows 用户也用上。在 AMD CPU 上约莫提速 100%。
这正是困惑的所在。extraNonce 不是区块头的一部分,它是第一笔交易的一部分。它并不会拖慢你的哈希。它并不改变头的大小…
其他参与者原话theymos原帖 ↗挖矿时,你计算的是区块头的哈希。哈希更多数据比哈希更少数据慢,因此区块头对所有人来说严格保持固定大小,只有一个例外。
这正是困惑的所在。extraNonce 不是区块头的一部分,它是第一笔交易的一部分。它并不会拖慢你的哈希。它并不改变头的大小。
我们务必保持警惕,把这个「区块内容会拖慢哈希速度」的误解扼杀在萌芽里。它并不会。
extraNonce 永远不需要很大。只要我们愿意,每秒时间字段变化时都能把它重置。最坏情况下,如果你不想跟踪递增,extraNonce 可以是 4 个随机字节,碰撞浪费时间的概率微乎其微。
各自独立的机器天然免疫碰撞,因它们在第一笔交易里有各自生成的公钥。这对每个线程同样成立。
ShadowOfHarbringer,你的机器用 -4way 更快吗?
ShadowOfHarbringer,你的机器用 -4way 更快吗?
如果这样,那我在想:所有支持 64 位的 AMD 是不是都有 128 位 SSE2。
我在这里发的 specialbuild 版本找的是型号 4 或更高。如果你的机器用 -4way 更快,那我就应该把它改成:任何支持 64 位的 AMD 都使用 SSE2。
忘了说,我本来就怀疑,这个检测在 64 位 AMD 上可能不起作用。我觉得难以置信,但 AMD 在 64 位模式下报告的型号…
已加入 SVN rev 152
SVN rev 150 加了一些代码,尝试自动检测是否使用 4 路 SSE2。我们需要它,因它只在拥有 128 位 SSE2…
SVN rev 150 加了一些代码,尝试自动检测是否使用 4 路 SSE2。我们需要它,因它只在拥有 128 位 SSE2 的某些较新 CPU 上更快,而在 64 位 SSE2 的 CPU 上无法提速。
它用 CPUID 指令获取 CPU 品牌、family、型号和 stepping。这是容易的部分。难的是知道该如何根据型号作出判断。我并未找到任何按 family、model、stepping 排列的 CPU 对照表,只能依据看到的零散报告。
这是我最终的结果:
// We need Intel Nehalem or AMD K10 or better for 128bit SSE2
// Nehalem = i3/i5/i7 and some Xeon
// K10 = Opterons with 4 or more cores, Phenom, Phenom II, Athlon II
// Intel Core i5 family 6, model 26 or 30
// Intel Core i7 family 6, model 26 or 30
// Intel Core i3 family 6, model 37
// AMD Phenom family 16, model 10
bool fUseSSE2 = ((fIntel && nFamily * 10000 + nModel >= 60026) ||
(fAMD && nFamily * 10000 + nModel >= 160010));我零星看到过一些互不一致的 AMD CPU 型号编号,因此不确定这能否识别出所有具备相应能力的 AMD 处理器。
如果判断错了,你仍然能用 -4way 或 -4way=0 覆盖。
它会把检测结果打进 debug.log。搜 CPUID。
只有使用 GCC 构建时才启用。
AMD Phenom(应该是 4 核)CPU 用 -4way 能跑到约 11,000khps,提速约 100%。24 核应该…
其他参与者原话BitLex原帖 ↗AMD X3 @2.8ghz
->官方客户端
~3800khs ~150Watt
你试过 -4way 吗?
引用 · 发言者未注明一台 24 核机器预计能达到多高的哈希速率?我有一台四核在跑 4,300 hashes-per-second,因此我估计 24 核机器能以 25,000 hashes-per-second 挖比特币。
AMD Phenom(应该是 4 核)CPU 用 -4way 能跑到约 11,000khps,提速约 100%。24 核应该能到 66,000khps。AMD 是最佳选择,因它的 SSE2 实现最好。(也可能只是因为 tcatm 手头是 AMD,把代码针对它做了优化)
事情太多,我还没来得及把 -4way 做成自动的。目前你仍然得手动开。
这个简化是有意的。134,217,728 个情况里才会出现一次多个 thash[7]=0。这只会使计算速度下降 0.0000…
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
这个简化是有意的。134,217,728 个情况里才会出现一次多个 thash[7]=0。这只会使计算速度下降 0.0000007%。
这大概解释了为什么超线程能提升 -4way 的性能。如果三个 SSE2 单元有富余,超线程正好能让它们都忙起来。
谢谢澄清。我看过有人贴的链接,说 AMD 约莫在 2007 年前后做了这个改动,但我不知道 Intel 那边的情况。
谢谢澄清。我看过有人贴的链接,说 AMD 约莫在 2007 年前后做了这个改动,但我不知道 Intel 那边的情况。
那 Core/Core2 就没戏了。它们只有一半的 SSE2 硬件。
奇怪的是 Intel 有 3 个 128 位单元,但只有 2 个 128 位单元的 AMD 反而更快。
这是我头一次听人说 i5 更慢。其他人都说 i5 上 4way 更快,开了超线程后更是这样。
VIA C7 的硬件 SHA-256 公布的性能数字并不惊人。只有 1500 khash/s 左右。想想就知道,用硬件实现并…
VIA C7 的硬件 SHA-256 公布的性能数字并不惊人。只有 1500 khash/s 左右。想想就知道,用硬件实现并不意味着快得离谱。每一步还是得做。只有简化为专用硬件后,体积小到能够并行放下很多个,才可能大幅提速。这未必容易,也不是理所当然。
我把 sha256.cpp 包进了
cpu family 6 model 26 stepping 4 是 Intel Core i7。
有点奇怪……我们确定这是同一个东西吗?tcatm,试试 amdfam10,确认测出来的速度一样。
GCC 4.3.3 不支持 -march=amdfamk10。我得到:
其他参与者原话tcatm原帖 ↗我建议用 -O3 -march=amdfamk10 编译 sha256.cpp(32 位和 64 位都能用),因为只有支持这套指令集的 CPU(AMD Phenom、Intel i5 及更新)才能从 -4way 受益,而且能带来约 9% 的性能提升。
GCC 4.3.3 不支持 -march=amdfamk10。我得到:
sha256.cpp:1: error: bad value (amdfamk10) for -march= switch
其他参与者原话NewLibertyStandard原帖 ↗用 4way 时,启用全部虚拟核心会明显更好。我觉得超线程关闭时,开不开 4way 哈希量差不多。
嘿,你也许发现了什么!
之前超线程没好处,是因为所有工作都发生在超线程共享的算术逻辑单元里。
tcatm 的 SSE2 代码一定是普通 x86 指令和 SSE2 指令的混合体,这样一个线程跑 x86 代码时,另一个就能跑 SSE2。
开超线程你提升了多少?
给几个数字?那是什么 CPU?
我刚上传了一个快速构建,好让测试者确认我编译得对不对。(我没有 i5 也没有 AMD)如果验证通过,我再打包完整发布包、走完…
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
我刚上传了一个快速构建,好让测试者确认我编译得对不对。(我没有 i5 也没有 AMD)如果验证通过,我再打包完整发布包、走完发布流程。
希望有人能拿 i5 或 AMD 测一下,确认我编译得没问题。我手头这两样都没有。
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
希望有人能拿 i5 或 AMD 测一下,确认我编译得没问题。我手头这两样都没有。
我也好奇它在 32 位 Linux 上是不是比 64 位差很多。
0.3.10 把 tcatm 的 4 路 SSE2 作为可选开关加入。
0.3.10 把 tcatm 的 4 路 SSE2 作为可选开关加入。
用开关 "-4way" 打开。不加开关则使用 Crypto++ ASM SHA-256。
我只在 Linux 上跑通了它。
下载:
0.3.10 见 http://bitcointalk.org/index.php?topic=827.0
请反馈你的 CPU 型号和测试结果!目前比较清楚的是 Core 2 及以下更慢,i5 更快。还没听到任何 i7 的成绩。我们还需要了解 AMD 各型号或其他较少见 CPU 的情况。
在 MinGW GCC 4.4.1 和 4.5.0 上,我都是用 test.cpp 能跑通,但被 BitcoinMiner …
在 MinGW GCC 4.4.1 和 4.5.0 上,我都是用 test.cpp 能跑通,但被 BitcoinMiner 调用时就 SIGSEGV。所以现在看来不是 GCC 版本的问题,而是别的什么,可能只是看栈是否碰巧对齐了。
在 Ubuntu 32 位的 GCC 4.3.3 上我这边运行正常。
我找到了 MinGW 4.5.0 上 Crypto++ 的问题。这是对应的补丁:
--- \old\sha.cpp Mon Jul 26 13:31:11 2010
+++
ew\sha.cpp Sat Aug 14 20:21:08 2010
@@ -336,7 +336,7 @@
ROUND(14, 0, eax, ecx, edi, edx)
ROUND(15, 0, ecx, eax, edx, edi)
- ASL(1)
+ ASL(label1) // Bitcoin: fix for MinGW GCC 4.5
AS2(add WORD_REG(si), 4*16)
ROUND(0, 1, eax, ecx, edi, edx)
ROUND(1, 1, ecx, eax, edx, edi)
@@ -355,7 +355,7 @@
ROUND(14, 1, eax, ecx, edi, edx)
ROUND(15, 1, ecx, eax, edx, edi)
AS2( cmp WORD_REG(si), K_END)
- ASJ( jne, 1, b)
+ ASJ( jne, label1, ) // Bitcoin: fix for MinGW GCC 4.5
AS2( mov WORD_REG(dx), DATA_SAVE)
AS2( add WORD_REG(dx), 64)Crypto++ 不能用,X86_SHA256_HashBlocks() 一直不返回
MinGW GCC 4.5.0:
Crypto++ 不能用,X86_SHA256_HashBlocks() 一直不返回
我只有用 test.cpp 时才让 4 路并行跑起来,被 BitcoinMiner 调用时就不行
MinGW GCC 4.4.1:
Crypto++ 能用
4 路并行 SIGSEGV
GCC 显然没有对齐 __m128i。
即使我们自己把 __m128i 变量对齐了,编译器也可能在后台用 __m128i 当临时变量。
把我们的 __m128i 变量对齐、并把这几处 inline 改成 define 之后,我让它在 4.4.1 上用 -O0 跑通了:
#define Ch(b, c, d) ((b & c) ^ (~b & d))
#define Maj(b, c, d) ((b & c) ^ (b & d) ^ (c & d))
#define ROTR(x, n) (_mm_srli_epi32(x, n) | _mm_slli_epi32(x, 32 - n))
#define SHR(x, n) _mm_srli_epi32(x, n)但那是在 -O0 下。
在 32 位上用 MinGW GCC 4.5 把测试跑通了。在 Core 2 上比官方版正好慢 50%。
如果你还没试过,试试把 thash 对齐。可能有影响,反正没坏处。
Windows 上的 MinGW 编译它会有问题:
Windows 上的 MinGW 编译它会有问题:
g++ -c -mthreads -O2 -w -Wno-invalid-offsetof -Wformat -g -D__WXDEBUG__ -DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/gcc_lib/mswud" -I"/wxwidgets/include" -msse2 -O3 -o obj/sha256.o sha256.cpp
sha256.cpp: In function `long long int __vector__ Ch(long long int __vector__, long long int __vector__, long long int __vector__)':
sha256.cpp:31: internal compiler error: in perform_integral_promotions, at cp/typeck.c:1454
Please submit a full bug report,
with preprocessed source if appropriate.
See
make: *** [obj/sha256.o] Error 1
速度竟然相差 4 倍或 6 倍,感觉很可能是旧芯片在某个特殊环节上存在短板,或者执行某条指令时特别慢。除非 i5 确实把 S…
速度竟然相差 4 倍或 6 倍,感觉很可能是旧芯片在某个特殊环节上存在短板,或者执行某条指令时特别慢。除非 i5 确实把 SSE2 的速度提高到原来的六倍当作了一项宣传卖点。
简单汇总一下:
Xeon Quad 慢 41%
Core 2 Duo 慢 55%
Core 2 Duo 持平 (vess)
Core 2 Quad 慢 50%
Core i5 快 200% (nelisky)
Core i5 快 100% (vess)
AMD Opteron 快 105%
aceat64:
我的系统从约 7100 降到了约 4200。
这台机器配的是双 Intel Xeon 四核 CPU (E5335) @ 2.00GHz。
impossible7:
在一台跑 x86_64 linux 的 Intel Core 2 Duo T7300 上,相比官方版本 (r121) 慢了 55%
nelisky:
我的 Core2Quad (Q6600) 慢了 50%,
我的 i5 提升了约 200%,
impossible7:
在一台跑 x86_64 linux 的 AMD Opteron 2374 HE 上,我得到了 105% 的提升 (!)
我上传了 Linux 版 0.3.8.1,其中的 64 位版本已重新编译。我用它跑了难度 1 测试,能生成区块。
我上传了 Linux 版 0.3.8.1,其中的 64 位版本已重新编译。我用它跑了难度 1 测试,能生成区块。
http://bitcointalk.org/index.php?topic=765.0
下载:
我发现 SSE2 只带来 2% 的轻微提速,似乎不值得为之牺牲兼容性。我选了更保守的方案。
我发现 SSE2 只带来 2% 的轻微提速,似乎不值得为之牺牲兼容性。我选了更保守的方案。
在我看来 Crypto++ 不像是在运行时决定是否用 SSE2。有一处它检测 SSE2 是为了决定某个块数参数,但 SSE2 相关的东西在编译期全是 #ifdef,我看不出它在运行时怎么切换。也许我没找对地方。
我们该在所有 makefile 里启用 SSE2 吗?看起来必须,万一有人用 64 位编译。
我会重编 Linux 0.3.8 发布版的 64 位部分。
抱歉。CRITICAL_BLOCK 并不完美。你得小心,别用 break 或 continue 跳出这个代码块。有一个 as…
其他参与者原话impossible7原帖 ↗CRITICAL_BLOCK 是一个包含 for 循环的宏。断言失败说明循环体里调用了 break。这个块里唯一的 break 语句在第 2762 行。原始源文件里这个临界块中并没有 break 语句。我认为你必须删掉 2759-2762 行。原始 main.cpp 里没有这种东西。
抱歉。CRITICAL_BLOCK 并不完美。你得小心,别用 break 或 continue 跳出这个代码块。有一个 assert 会检测到 break 并发出警告。我使用这个宏的做法或许值得批评,但没有它,语法会臃肿得多,也更容易出错。
有没有可能 SSE2 代码在 Intel 上慢是因为某种可以绕过的怪癖?比如,某个东西不对齐时能工作但很慢,或者缓存颠簸,或者某条指令特别慢?我不确定这东西还找不找得到,但 Intel 以前好像有个能按指令级别做性能分析的分析器。我猜如果 tcatm 手头没有装那种慢处理器的机器可测,希望就不大。但它要是能在大多数 CPU 上跑起来就太好了。
是在 AMD 上速度为原来的 2 倍,而在 Intel 上只有原来的 1/2 吗?
也就是说,你用 128 位寄存器,通过 SIMD 一次处理四个 32 位数据?这事我想了很久,但因为加法会进位到相邻的值,我…
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
太神了……
也就是说,你用 128 位寄存器,通过 SIMD 一次处理四个 32 位数据?这事我想了很久,但因为加法会进位到相邻的值,我一直以为不可能。
难道我在 OSX 构建里就弄坏了这一处?!只改这一处之后真的能跑?
难道我在 OSX 构建里就弄坏了这一处?!只改这一处之后真的能跑?
makefile.vc 我也不得不这么干。编译通过了,但 SHA-256 不正确;每次都返回同一个错误的哈希。
我们先禁用它,等有人想出修法再启用。光是 midstate 优化就还有 1.7 倍的速度。
Crypto++ 的 ASM SHA-256 在 Linux 和 Windows(MinGW)的 GCC 下正常。
我把这个 makefile.osx 改动传到了 SVN。(告诉我现在能否编译通过)
好,谢谢。我还想知道只要不开 Generate,它是不是就能正常跑。照理说只要不实际执行任何 SSE2 指令,它应该还是能加…
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
好,谢谢。我还想知道只要不开 Generate,它是不是就能正常跑。照理说只要不实际执行任何 SSE2 指令,它应该还是能加载的。至少 Pentium 3 应该能在不生成的情况下跑它。
我把 Crypto++ 5.6.0 库的一个子集加进了 SVN。裁剪到只剩 SHA 和 11 个通用依赖文件。除了 SHA …
其他参与者原话BlackEye原帖 ↗我成功把 Crypto++ 5.6.0 的 SHA256 功能集成进了 Bitcoin。这是迄今最快的 SHA256,用的是 SSE2 汇编代码。由于 Bitcoin 传给块哈希函数的是非对齐数据,我得把 MOVDQA 指令换成 MOVDQU。
我认为用 Crypto++ 5.6.0 的 SHA256 功能是当下的正路。
我把 Crypto++ 5.6.0 库的一个子集加进了 SVN。裁剪到只剩 SHA 和 11 个通用依赖文件。除了 SHA 不应该有其他密码学内容。
我把数据字段对齐了,就成功了。ASM SHA-256 快了约 48%。综合下来,速度约为 0.3.3 版本的 2.5 倍。
我猜它用的是 SSE2。它会在编译时根据编译器环境自动设置构建配置。
看起来它在运行时有一些 SSE2 检测,但很难判断不可用时是否真的会回退。我希望发布构建带 SSE2。SSE2 从第一代 Pentium 4 就有了。Pentium 3 或更老的机器慢成那样,用它们生成纯属浪费电费。
这是 SVN rev 114。
我把缓存 SHA256 状态的思路加进了 SVN,rev 113。提速约 70%。根据你在 x64 主题里的帖子,功劳记在 …
其他参与者原话Olipro原帖 ↗Crypto++ 5.6.0:http://www.cryptopp.com/
Cached SHA256:http://pastebin.com/rJAYZJ32(虽然我很确定这在别处也公开发表过,我是从 IRC 被链接过去的)
我把缓存 SHA256 状态的思路加进了 SVN,rev 113。提速约 70%。根据你在 x64 主题里的帖子,功劳记在 tcatm 名下。
我能用 MinGW 编译 Crypto++ 5.6.0 的 ASM SHA 代码,但一运行就崩溃。它说自己是给 MASM(微软的汇编器)的,他们给的示例命令行看起来像 Visual C++。是不是只能在 MSVC 和 Intel 编译器下用?
这仍然是基于 Crypto++ 改的吗?把它弄进主源代码吧。
OpenSSL 没有提供只执行 SHA256 底层数据块哈希计算的接口。SHA256 一开始要把你的数据包进一个特殊格式的缓…
OpenSSL 没有提供只执行 SHA256 底层数据块哈希计算的接口。SHA256 一开始要把你的数据包进一个特殊格式的缓冲区。如果像我们这样只对一两个数据块做哈希计算,搭建缓冲区花的时间比实际哈希还长一个量级。它本来是设计给哈希几 KB、几 MB 数据时摊薄开销用的。在 BitcoinMiner 里,我们把缓冲区搭一次然后反复复用。
如果你能找到(在 MinGW/GCC 下)比我们现有的更快的 SHA256 代码,那真是太好!(不过要留意许可证)我们现在这个是我试过的唯一一个,所以很有可能还有改进空间。
2 年多前我写它的时候,已有速度极快的 SHA1 实现,SHA256 却很少受到关注。这么长时间足够他们拿出更好的东西了。当时 SHA256 比最快的 SHA1 慢得超出我的预期。SHA256 应该比 SHA1 慢一些,但不该慢那么多。
(希望你不介意我把你的主题改了名,SHA-256 优化很重要,我却老忘了这茬)
能,但生成速度不到原来的一半。
MinGW 仍然只有老当益壮的稳定版 3.4.5。他们没多少理由去更新它。
MinGW 仍然只有老当益壮的稳定版 3.4.5。他们没多少理由去更新它。
我看 3.4.5 编译出的 SHA 反汇编时,完全看不出有任何改进余地。我无法想象还能从里面再挤出 8%。有没有可能 Windows 本身就有 8% 的额外开销?不做系统调用之类的,纯粹是忙于计算的代码,任务切换和其他管理性操作能吃掉这么多吗?
谢谢 virtualcoin,完美的对比。
谢谢 virtualcoin,完美的对比。
32 位 Windows(2310k)到 32 位 Linux(2500k)的 8% 提速,大概来自 Linux 上更新的 GCC(4.4.3 对 3.4.5)。
32 位到 64 位 Linux 的 15% 提速就更神秘了。代码是完全的 32 位。
嗯,我想是 x86-64 多出的那 8 个寄存器在起作用。如果 SHA 能把16 个状态变量中的大部分装进寄存器,那会带来显著差异。
我不知道。也许更有 Linux 经验的人知道怎么装它需要的库。
我不知道。也许更有 Linux 经验的人知道怎么装它需要的库。
我是在 Ubuntu 10.04 上构建的。我希望那不是个错误。也许应该构建在更老的版本上以获得更多向后兼容。Linux 上有这个问题吗:在最新版上构建,在旧版上就不好使?在 10.04 上我有什么办法降级到旧版 GCC 吗?
64 位版不应比 32 位版快,但如果有人能对两个 linux 版本做一次并排对比、核实一下就太好了。SHA-256 是 32 位算法,BitcoinMiner 里完全没有用到 64 位。
Windows 我们不必费心做 64 位版。32 位程序能在所有版本的 Windows 上运行。不像 Linux,64 位系统非要用 64 位程序。
我也好奇它在 linux 上是不是比 windows 上稍快一点。
你觉得我该把目录做成:
/bin32/
/bin64/
还是
/bin/32/
/bin/64/
Laszlo 发现开启更多优化能把性能提高约 20%,所以 0.3 比 0.2.0 的哈希速度快 20%,但我猜他自己的构建…
这条发言承接前面的讨论,可通过下方入口查看完整上下文。
Laszlo 发现开启更多优化能把性能提高约 20%,所以 0.3 比 0.2.0 的哈希速度快 20%,但我猜他自己的构建里已经用了。
增加 30khash 之后,总速率是多少?(好算百分比)
我注意到哈希性能在不同 CPU 之间的差距没有预期的大。与老 CPU 相比,新 CPU 在哈希上的提速远不如它在通用基准测试…
我注意到哈希性能在不同 CPU 之间的差距没有预期的大。与老 CPU 相比,新 CPU 在哈希上的提速远不如它在通用基准测试上的表现。
我猜近来的 CPU 优化肯定集中在 I/O 和分支预测之类的方面。大多数程序无非是一堆内存访问、比较和跳转,很少会长时间埋头做数学运算。
最新的 SVN 版本有 khash/s 显示。每个处理器大约 400 khash/s 是典型水平。
好主意。我还不确定具体放在哪儿,但它完全可以计算出区块生成之间的预期平均时间,这样人们就知道该期待什么了。
好主意。我还不确定具体放在哪儿,但它完全可以计算出区块生成之间的预期平均时间,这样人们就知道该期待什么了。
每个节点、每个处理器在其区块里都有不同的公钥,所以可以保证它们搜索的是不同的计算空间。
每当 32 位 nonce 从 1 重新开始时,bnExtraNonce 就会递增,它是一个任意精度整数。
全网平均每天挖出的比特币总量不会因此改变。快的机器,只是比慢的机器分到更大的一份而已。即便人人都买了更快的机器,也并不会比从…
全网平均每天挖出的比特币总量不会因此改变。快的机器,只是比慢的机器分到更大的一份而已。即便人人都买了更快的机器,也并不会比从前得到更多的比特币。
我们应该达成一个君子协定:为了整个网络的利益,尽可能推迟 GPU 军备竞赛。如果新用户不必操心 GPU 驱动与兼容性,让他们上手就会容易许多。如今,光凭一个 CPU 的人,就能相当公平地参与竞争,这很好。
v0.1.6 接下来要做的是利用多个处理器生成区块。目前它只启动一个线程。如果你有 Core Duo 或
引用的来信Nicholas Bohm来源 ↗下一步是什么?
v0.1.6 接下来要做的是利用多个处理器生成区块。目前它只启动一个线程。如果你有 Core Duo 或 Quad 这样的多核处理器,产量就会翻倍或增至四倍。
之后我想添加接口,让任何服务器端语言都能很容易地把它集成到网站中。
Satoshi
矿池与外部矿工程序
6 条
ribuck 的描述非常准确。
ribuck 的描述非常准确。
矿池运营者能修改他们的 getwork,多加一个参数:你的分成应发送到的地址。
对矿池运营者来说,简单的做法是等下一个区块被找到后按比例分配:
用户的近似命中数/所有人的近似命中总数
这样起步更容易也更安全。它还有个好处:同一用户的多次命中能合并成一笔交易。通常会有很多次命中来自同一批人。
要让用户立即拿到回报,可以在每次近似命中后立即支付固定金额;这样,运营者就要承担随机性带来的风险,因为在找到区块之前,近似命中的次数可能多,也可能少。
无论哪种方式,提交解出区块的那次命中的用户应该先从总额中额外获得一笔奖励,比如 10 BTC。
新用户其实甚至不需要 Bitcoin 软件。他们能下载一个挖矿程序,在 mtgox 或 mybitcoin 开个账户,把存款地址填进挖矿程序,再连接到任意一家矿池服务器。挖矿程序显示找到了东西之后,过一会儿账户里就会出现几个币。
挖矿程序的作者最好确保程序绝不误报近似命中。用户要靠这个来检查矿池运营者有没有作弊。如果挖矿程序错误地报告找到了东西,用户去查账户、什么都没找到,就会迁怒于矿池运营者。
它就是这么做的,返回 true/false。
getwork 负责字节反转。midstate、data 和 hash1 已经是大端序,你把 data 按大端序传回去即可,…
其他参与者原话jgarzik原帖 ↗我怀疑 ByteReverse(或缺少它)有什么古怪。'data' 和 'nonce' 到底要不要字节反转、怎么反转,相当不清楚。
getwork 负责字节反转。midstate、data 和 hash1 已经是大端序,你把 data 按大端序传回去即可,因此你全程用大端序工作,不需要做任何字节反转。它们与传给 ScanHash_ 函数的是同一份数据。你能把 midstate、data 和 hash1 放进 16 字节对齐的缓冲区,传给 ScanHash_ 函数,比如 ScanHash(pmidstate, pdata + 64, phash1, nHashesDone)。找到 nonce 后,把它补进 data 再调用 getwork。
我或许应该把 ScanHash_ 函数改成用 pdata 而不是 pdata + 64,这样更一致。
target 是小端序,按预期应该与 m0mchil 的做法一致。(如果不是,那就应该修正。)这是唯一需要你做字节反转的地方。我猜是这样:if ByteReverse((unsigned int*)hash[6]) < (unsigned int*)target[6]。
其他参与者原话DiabloD3原帖 ↗中本聪,请修正你的 getwork 实现,使其符合 m0mchill 的规范
这就是新规范。更新你的挖矿程序来使用这套接口,应该不难。
变化有:
- 提交疑似命中时不返回新工作,只有不带参数调用时才返回。
- 区块字段已拆分为 data 和 hash1。
- state 改名为 midstate,保持一致性。
- 不再需要 extranonce。
修订版 getwork 已经进了官方客户端,但矿工程序需要稍微更新一下才能使用。
它不是严格意义上的即插即用替代品。我想把接口稍微清理一下。只需要改几处。
它不是严格意义上的即插即用替代品。我想把接口稍微清理一下。只需要改几处。
ScanHash_ 函数不会消失。顺带一提,这个接口的参数设计与那组函数保持一致(midstate, data, hash1)。
我把 m0mchil 的 getwork 重新设计后上传到了 SVN r189(版本号 31601)
我把 m0mchil 的 getwork 重新设计后上传到了 SVN r189(版本号 31601)
m0mchil 的外部比特币挖矿程序的构想解决了很多问题。GPU 编程不成熟、编译困难,我不想给构建加更多依赖。getwork 让这些问题得以分开解决——不同的硬件和操作系统用不同的程序。服务器集群能只跑一个 Bitcoin 节点、其余全跑 getwork 客户端,这也很方便。
接口有几处变化:
getwork [data]
如果未指定 [data],返回格式化的待运算哈希数据:
"midstate":哈希完数据前一半之后的预计算哈希状态
"data":区块数据
"hash1":用于第二次哈希的格式化哈希缓冲区
"target":小端序哈希目标
如果指定了 [data],则尝试解出该区块,成功时返回 true。[data] 就是 "data" 字段返回的那 128 字节区块数据,只是改了 nonce。
注意事项:
- 提交疑似命中时不返回新工作,只有不带参数调用时才返回。
- 区块字段已拆分为 data 和 hash1。
- data 为 128 字节,包含已被 midstate 哈希过的前一半。
- hash1 恒定不变,但为方便仍一并给出。
- "ThreadRPCServer method=getwork" 的日志已禁用,否则日志里垃圾太多。
目录与阅读顺序由本站整理;原话保留各自日期与上下文。文中软件版本、费用和设置属于当时的历史语境。