Filecoin系列 - 源码分析 - CPU SHA扩展

CPU指令集 - SHA扩展 (SHA extensions)

  • Intel CPU的并行能力与浮点性能更强
  • AMD CPU支持SHA扩展, 计算SHA的性能更强

Intel CPU的浮点性能更强,是因为Intel的最大峰值性能凭借原生256bit向量指令集和寄存器的帮助,拥有对手两倍的峰值潜力,而AES是因为Intel明显偷懒,因为有了FMA而将乘加运算器依附于FMA运算器,使得乘加混合的计算峰值在无FMA指令集帮助下与对手没有优势,而SHA的性能,则是专用电路的胜利,但AMD的指令集也不是万能的,比如他不支持SHA-512,不过SHA-512用的少.

Lotus内检测并启用sha-ni功能的相关代码

看了下源码, 发现P1算法本身会检测CPU是否支持 sha extensions, 如果支持, 会采用加速算法.

rust-fil-proofs/sha2raw/src/platform.rs: 检测代码

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
    #[allow(unreachable_code)]
    pub fn sha_if_supported() -> Option<Self> {
    
    
        // Use raw_cpuid instead of is_x86_feature_detected, to ensure the check
        // never happens at compile time.
        let cpuid = CpuId::new();
        let is_runtime_ok = cpuid
            .get_extended_feature_info()
            .map(|info| info.has_sha())
            .unwrap_or_default();

        #[cfg(target_feature = "sha")]
        {
    
    
            if !is_runtime_ok {
    
    
                println!("WARN: sha-ni not available, falling back");
            }
        }

        // Make sure this computer actually supports it
        if is_runtime_ok {
    
    
            return Some(Implementation(Platform::Sha));
        }

        None
    }

rust-fil-proofs/sha2raw/src/sha256_intrinsics.rs: SHA extensions 的实现代码

pub unsafe fn compress256(state: &mut [u32; 8], blocks: &[&[u8]]) {
    
    
	...
}

Benchmark 时的问题

如果将启用了加速算法的二进制文件放到intel上测试,会输出WARN: sha-ni not available, falling back,因为不支持sha extensions.

是什么原因导致此警告?
也许您应该使用支持sha-ni扩展的AMD CPU.

这是否意味着不能使用英特尔CPU运行平台?
由于型号AMD CPU具有SHA扩展,因此具有显着改进。

检查cpu是否支持 sha-ni 扩展

  1. [推荐]看less /proc/cpuinfo内是否有 sha_ni 字样 (intel的没有的)
cat /proc/cpuinfo | grep sha_ni
  1. 通过查找宏__SHA__,可以在Linux上的预处理器中检测SHA的可用性。-march=native将使其在处理器本机时可用。否则,您可以使用-msha启用它。 (intel的没有的)
$ gcc -march=native -dM -E - </dev/null | egrep -i '(aes|rdrnd|rdseed|sha)'
#define __RDRND__ 1
#define __SHA__ 1
#define __RDSEED__ 1
#define __AES__ 1
  1. 代码检测
//testcpu.cpp

#include <iostream>

int CheckForIntelShaExtensions() {
    
    
   int a, b, c, d;

   // Look for CPUID.7.0.EBX[29]
   // EAX = 7, ECX = 0
   a = 7;
   c = 0;

   asm volatile ("cpuid"
        :"=a"(a), "=b"(b), "=c"(c), "=d"(d)
        :"a"(a), "c"(c)
       );

   // Intel® SHA Extensions feature bit is EBX[29]
   return ((b >> 29) & 1);
}

int main(int argc, const char** argv) {
    
    
	int res = CheckForIntelShaExtensions();
	printf("CheckForIntelShaExtensions: %s \n", res==1?"true":"false" );
	return 0;
}

g++ testcpu.cpp -o testcpu && ./testcpu

  1. 可运行lotus/extern/filecoin-ffi/install-filcrypto 检测脚本
# 先修改`lotus/extern/filecoin-ffi/rust/rustc-target-features-optimized.json`
"rustc_target_feature": "+sha",
"check_cpu_for_feature": null
|
V
"rustc_target_feature": "+sha",
"check_cpu_for_feature": "sha_ni"

# 再运行, 如果不支持sha,会提示 "your CPU does not support the"
./install-filcrypto

openssl speed 测试sha性能

A C/C++ programmer is probably best off using OpenSSL, which will use whatever CPU features it can to hash quickly. (Including SHA extensions on CPUs that have them, if your version of OpenSSL is new enough. >= v1.0.2)

  1. Generated a checksum of a big file with openssl
# 任意找一个几个G的大文件
$ time openssl dgst -sha256 /var/tmp/filecoin-proof-parameters/v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.params 
#这是intel的性能
openssl dgst -sha256   4.21s user 0.17s system 99% cpu 4.382 total
  1. openssl speed

这是intel的性能

$ openssl speed sha1
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
sha1            120593.54k   300683.29k   570650.03k   772621.99k   872868.52k   865457.49k

$ openssl speed sha256
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
sha256           77305.80k   172220.71k   317703.34k   413427.71k   461886.81k   459887.96k

AMD的性能暂时没法测试(我的电脑是Intel的)

如果存在,OpenSSL会使用硬件加速。

使用基准测试OpenSSL speed SHA256,块大小为8KiB时,速度可以提高了550%。

对于加载到RAM的实际1GB和5GB文件,散列速度大约快3倍。

总结

  • 源码中P1算法本身会检测CPU是否支持 sha extensions, 如果支持, 会采用加速算法.
  • 如果将启用了加速算法的二进制文件放到intel上测试,会输出WARN: sha-ni not available, falling back,因为不支持sha extensions.
  • 如要看cpu是否支持sha extensions, 查看less /proc/cpuinfo返回的信息内是否有 sha_ni 字样.

往期精彩回顾:
区块链知识系列
密码学系列
零知识证明系列
共识系列
公链调研系列
比特币系列
以太坊系列
EOS系列
Filecoin系列
联盟链系列
Fabric系列
智能合约系列
Token系列

猜你喜欢

转载自blog.csdn.net/wcc19840827/article/details/118487819