AD
首页 > 数字货币 > 正文

浅析Filecoin - SDR机能的优化道理_数字货币

[2021-02-04 07:52:24] 来源: 编辑:wangjia 点击量:
评论 点击收藏
导读: Filecoin官方于9.28日正式发布了SDR的优化版本。在新版本中,AMD3970x的P1阶段性能2小时10分钟,通过观察官方的优化思路,P1性能优化的核心Patch如下: 从底层逻辑就清楚的告
Filecoin官方于9.28日正式发布了SDR的优化版本。在新版本中,AMD3970x的P1阶段性能2小时10分钟,通过观察官方的优化思路,P1性能优化的核心Patch如下:

从底层逻辑就清楚的告诉你,比特币是你值得期待的头号数字资产!

从底层逻辑就清楚的告诉你,比特币是你值得期待的头号数字资产!

Filecoin官方于9.28日正式宣告了SDR的优化版本。在新版本中,AMD3970x的P1阶段机能2小时10分钟,经由历程视察官方的优化思绪,P1机能优化的中心Patch以下:

commit 0313c663c1b4c7ea891dcaf7245e2cc5eb4b1f81
Author: dignifiedquire me@dignifiedquire.com
Date:   Thu Aug 27 23:08:12 2020 +0200

  Optimize Phase1.

这个Patch在8月27号就做出来了。优化思绪比较清楚:经由历程预读取base/exp parent的数据,让数据的预备和sha256的盘算并行。在引见详细的优化逻辑之前,引见一下AMD CPU架构的小学问:

1. Core ComplexCCX是AMD CPU架构的一个术语。CCX - CPU Core Complex。CCX指的是一组(4个)CPU中心和缓存(L1/L2/L3)。4个CCX一组,也有一个特地的术语 - CCD (Core Chiplet Die)。AMD的Ryzen 3000系列的处置惩罚器都采纳相似的架构。

全部芯片由两个die构成(上面是die0,下面是die1)。每一个Die(CCD)包含两个CCX。注重的是,每一个core都有自身的L1/L2缓存,然则L3缓存是几个Core同享的。也就是说,在CCX的四个核能够同享L3缓存,假如四个核须要接见统一段数据,能够加快数据的接见时刻。

2. SDR算法优化思绪

优化之前盘算一层的某个节点是如许的:

图片2_副本.png

在盘算某个节点时,暂时猎取exp/base的parent节点信息,再举行sha256的盘算。

优化后的盘算体式格局以下:

图片3_副本.png

优化的思绪,就是将exp/base的parent节点信息的猎取和sha256的盘算并行。在举行节点盘算之前,预先读取exp/base的节点信息并保存在sdr_parent_cache环缓冲中。注重,sdr_parent_cache和parent_cache不一样。sdr_parent_cache是某个节点依靠的多个节点的信息,parent_cache是节点依靠信息的缓存。Filecoin官方称这个优化是Multi-core优化,有几个缘由:1/ 节点依靠数据的预读取和节点的盘算由多核完成。2/ 预读取的逻辑自身也是由多核完成。

3. SDR算法优化逻辑剖析

明白了优化思绪,SDR算法优化的代码照样比较轻易明白的。中心逻辑在storage-proofs/porep/src/stacked/vanilla/create_label/mult.rs代码的create_layer_labels函数中。

fn create_layer_labels(
  parents_cache: CacheReader u32 ,
  replica_id: [u8],
  layer_labels: mut MmapMut,
  exp_labels: Option mut MmapMut ,
  num_nodes: u64,
  cur_layer: u32,
) - Result () {

parents_cache是节点依靠关联的cache数据,replica_id是replia的编号信息,layer_labels和exp_labels分别是当前层和上一层的数据,num_nodes节点个数,cur_layer是当前层的编号。

逻辑的完成采纳“生产者/消费者“形式,生产者”生成“节点依靠数据,消费者猎取这些数据并举行sha256的盘算。

3.1 肯定生产者设置

生产者,经由历程多线程预读取某个节点依靠的节点数据。lookahead指预读取最大的节点个数。num_producers是运用若干个生产者。producer_stride是每一个生产者一次生产若干个节点的依靠数据。

  let (lookahead, num_producers, producer_stride) = if cur_layer == 1 {
      (400, 1, 16)
  } else {
      (800, 2, 128)
  };

在Layer为1时,采纳1个生产者,每一个生产者一次生产16个节点的依靠数据。其他Layer时,采纳2个生产者,每一个生产者一次生产128个节点的依靠数据。Layer为1和其他时刻区离开,是由于Layer1的依靠关联和其他层不一样。

3.2 请求Ring缓存

生产者预生成的节点依靠数据是经由历程Ring缓存(ring_buf)存储。这个存储在生产者和消费者之间同享。

  const BYTES_PER_NODE: usize = (NODE_SIZE * DEGREE) + 64;
  let mut ring_buf = RingBuf::new(BYTES_PER_NODE, lookahead);
  let mut base_parent_missing = vec![BitMask::default(); lookahead];

  // Fill in the fixed portion of all buffers
  for buf in ring_buf.iter_slot_mut() {
      prepare_block(replica_id, cur_layer, buf);
  }

须要解释一下base_parent_missing。由于base parent的节点须要当前层前面节点的盘算结果,在预读取的时刻,大概这些节点还没有盘算出来。这些节点的信息经由历程base_parent_missing标示出来。注重,ring_buf中的每一个节点的数据除了依靠的节点信息外,另有一些辅佐信息(replica_id, node_id等等)。这些辅佐信息的长度是64,所以BYTES_PER_NODE还会加上64。prepare_block函数就是预先添补辅佐信息。

3.3 请求原子锁操纵

生产者和消费者之间须要同步。多个生产者之间也须要同步。

  // Node the consumer is currently working on
  let cur_consumer = AtomicU64::new(0);
  // Highest node that is ready from the producer
  let cur_producer = AtomicU64::new(0);
  // Next node to be filled
  let cur_awaiting = AtomicU64::new(1);

cur_consumer和cur_producer就是用于生产者和消费者之间的同步。cur_awaiting用于多个生产者之间的同步。

3.4 启动生产者

设定了若干生产者,就启动个若干线程。每一个线程挪用create_label_runner函数,完成了详细的预读取逻辑。

      for _i in 0..num_producers {
          let layer_labels = layer_labels;
          let exp_labels = exp_labels.as_ref();
          let cur_consumer = cur_consumer;
          let cur_producer = cur_producer;
          let cur_awaiting = cur_awaiting;
          let ring_buf = ring_buf;
          let base_parent_missing = base_parent_missing;

          runners.push(s.spawn(move |_| {
              create_label_runner(
                  parents_cache,
                  layer_labels,
                  exp_labels,
                  num_nodes,
                  cur_consumer,
                  cur_producer,
                  cur_awaiting,
                  producer_stride,
                  lookahead as u64,
                  ring_buf,
                  base_parent_missing,
              )
          }));
      }

详细的逻辑比较清楚易懂,感兴趣的小伙伴直接看源代码。

3.5 启动消费者

消费者的逻辑相对多一些。每一层的第一个节点由于没有base parent节点,盘算比较特别,零丁处置惩罚:

      let mut buf = [0u8; (NODE_SIZE * DEGREE) + 64];
      prepare_block(replica_id, cur_layer, mut buf);

      cur_node_ptr[..8].copy_from_slice( SHA256_INITIAL_DIGEST);
      compress256!(cur_node_ptr, buf, 2);

      // Fix endianess
      cur_node_ptr[..8].iter_mut().for_each(|x| *x = x.to_be());

      cur_node_ptr[7] = 0x3FFF_FFFF; // Strip last two bits to ensure in Fr

检察生产者供应了若干节点数据,并入手下手举行处置惩罚:

          let ready_count = producer_val - i + 1;
          for _count in 0..ready_count {
              cur_node_ptr = mut cur_node_ptr[8..];
              // Grab the current slot of the ring_buf
              let buf = unsafe { ring_buf.slot_mut(cur_slot) };

处置惩罚历程分为两部份。第一部份,base parent有大概有缺失,先补充缺失的数据:

              for k in 0..BASE_DEGREE {
                  let bpm = unsafe { base_parent_missing.get(cur_slot) };
                  if bpm.get(k) {
                      // info!("getting missing parent, k={}", k);
                      let source = unsafe {
                          if cur_parent_ptr.is_empty() {
                              cur_parent_ptr =
                                  parents_cache.consumer_slice_at(cur_parent_ptr_offset);
                          }
                          // info!("after unsafe, when getting miss parent");
                          let start = cur_parent_ptr[0] as usize * NODE_WORDS;
                          let end = start + NODE_WORDS;

                          // info!("before as_slice(), when getting miss parent");
                          layer_labels.as_slice()[start..end]
                      };

                      buf[64 + (NODE_SIZE * k)..64 + (NODE_SIZE * (k + 1))]
                          .copy_from_slice(source.as_byte_slice());
                      // info!("got missing parent, k={}", k);
                  }
                  cur_parent_ptr = cur_parent_ptr[1..];
                  cur_parent_ptr_offset += 1;
              }

第二部份,在base parent数据补充完全后,一切的数据都已预备完成,举行sha256的盘算:

         if cur_layer == 1 {
                  // Six rounds of all base parents
                  for _j in 0..6 {
                      compress256!(cur_node_ptr, buf[64..], 3);
                  }

                  // round 7 is only first parent
                  memset( mut buf[96..128], 0); // Zero out upper half of last block
                  buf[96] = 0x80; // Padding
                  buf[126] = 0x27; // Length (0x2700 = 9984 bits - 1248 bytes)
                  compress256!(cur_node_ptr, buf[64..], 1);
              } else {
                  // Two rounds of all parents
                  let blocks = [
                      *GenericArray:: u8, U64 ::from_slice( buf[64..128]),
                      *GenericArray:: u8, U64 ::from_slice( buf[128..192]),
                      *GenericArray:: u8, U64 ::from_slice( buf[192..256]),
                      *GenericArray:: u8, U64 ::from_slice( buf[256..320]),
                      *GenericArray:: u8, U64 ::from_slice( buf[320..384]),
                      *GenericArray:: u8, U64 ::from_slice( buf[384..448]),
                      *GenericArray:: u8, U64 ::from_slice( buf[448..512]),
                  ];
                  sha2::compress256(( mut cur_node_ptr[..8]).try_into().unwrap(), blocks);
                  sha2::compress256(( mut cur_node_ptr[..8]).try_into().unwrap(), blocks);

                  // Final round is only nine parents
                  memset( mut buf[352..384], 0); // Zero out upper half of last block
                  buf[352] = 0x80; // Padding
                  buf[382] = 0x27; // Length (0x2700 = 9984 bits - 1248 bytes)
                  compress256!(cur_node_ptr, buf[64..], 5);
              }

盘算分为两种状况,一种是第一层的数据,一种是其他层的数据。盘算sha256的历程稍稍有些差别。至此,全部优化算法逻辑就完全了。

总结:

Filecoin官方宣告了SDR的优化版本。在AMD3970x上,P1的机能2小时10分钟。优化思绪比较清楚,经由历程预读取base/exp parent的数据,让数据的预备和sha256的盘算并行。

 

加入新手交流群:每天早盘分析、币种行情分析

添加助理微信,一对一专业指导:chengqing930520

上一篇:Filecoin挖矿的道理与机制
下一篇: 从底层逻辑就清晰的通知你,比特币是你值得期待的头号数字资产!

加入新手交流群:每天早盘分析、币种行情分析,添加助理微信

一对一专业指导:chengqing930520

最新资讯
提供比特币数字货币以太坊eth,莱特币ltc,EOS今日价格、走势、行情、资讯、OKEX、币安、火币网、中币、比特儿、比特币交易平台网站。

2021 数字货币 网站地图

查看更多:

为您推荐