难度校验算法优化
背景
https://github.com/starcoinorg/starcoin/pull/3056 jolestar 的amd ryzen cpu 校验不通过,发现这个算法是使用C++实现
然后rust使用ffi调用的
__m128d x = _mm_castsi128_pd(_mm_add_epi64(_mm_cvtsi64_si128(sqrt_input >> 12), exp_double_bias)); \
发现使用了sse2指令但是编译 build.rs只有-maes,并没有sse2指令
感觉这个应该可以使用sse2指令对其进行加速,尝试看有没有成熟的实现对其进行加速,实在没有再尝试自己去实现
找库
xmrig
找到一个实现
https://github.com/xmrig/xmrig/blob/master/src/crypto/cn/CnHash.cpp#L323 看起来这就是我要找的实现
xmrig::CnHash::CnHash()
{
ADD_FN(Algorithm::CN_0);
ADD_FN(Algorithm::CN_1);
ADD_FN(Algorithm::CN_2);
ADD_FN(Algorithm::CN_R);
ADD_FN(Algorithm::CN_FAST);
ADD_FN(Algorithm::CN_HALF);
ADD_FN(Algorithm::CN_XAO);
ADD_FN(Algorithm::CN_RTO);
ADD_FN(Algorithm::CN_RWZ);
ADD_FN(Algorithm::CN_ZLS);
ADD_FN(Algorithm::CN_DOUBLE);
ADD_FN_ASM(Algorithm::CN_2);
ADD_FN_ASM(Algorithm::CN_HALF);
ADD_FN_ASM(Algorithm::CN_R);
ADD_FN_ASM(Algorithm::CN_RWZ);
ADD_FN_ASM(Algorithm::CN_ZLS);
ADD_FN_ASM(Algorithm::CN_DOUBLE);
看第6行和17行这个实现有C++还有ASM实现,果然还是直接使用汇编性能最好,感觉和rust crypto hash sha2实现一个套路
再看下ADD_FN
#define ADD_FN(algo) do { \
m_map[algo] = new cn_hash_fun_array{}; \
m_map[algo]->data[AV_SINGLE][Assembly::NONE] = cryptonight_single_hash<algo, false, 0>; \
m_map[algo]->data[AV_SINGLE_SOFT][Assembly::NONE] = cryptonight_single_hash<algo, true, 0>; \
m_map[algo]->data[AV_DOUBLE][Assembly::NONE] = cryptonight_double_hash<algo, false>; \
m_map[algo]->data[AV_DOUBLE_SOFT][Assembly::NONE] = cryptonight_double_hash<algo, true>; \
m_map[algo]->data[AV_TRIPLE][Assembly::NONE] = cryptonight_triple_hash<algo, false>; \
m_map[algo]->data[AV_TRIPLE_SOFT][Assembly::NONE] = cryptonight_triple_hash<algo, true>; \
m_map[algo]->data[AV_QUAD][Assembly::NONE] = cryptonight_quad_hash<algo, false>; \
m_map[algo]->data[AV_QUAD_SOFT][Assembly::NONE] = cryptonight_quad_hash<algo, true>; \
m_map[algo]->data[AV_PENTA][Assembly::NONE] = cryptonight_penta_hash<algo, false>; \
m_map[algo]->data[AV_PENTA_SOFT][Assembly::NONE] = cryptonight_penta_hash<algo, true>; \
} while (0)
这个实现基于C++ template, 实现了处理单条消息,和2-5条消息并行计算的场景
我要处理的应该就是cryptonight_single_hash
这个函数
先编译下整个工程,编译成功后不知道怎么跑这个函数,感觉这个工程套的东西很多,工作量可能不是一天能处理的
再看看其他的还有https://github.com/xmrig/xmrig-cuda/blob/master/src/CryptonightR.cu 这个是gpu的实现,以后有空可以研究下
monero
https://github.com/monero-project/monero/tree/master/src/crypto 这个实现感觉简单的多,基本都是C的实现,感觉port起来应该容易的多