为了账号安全,请及时绑定邮箱和手机立即绑定

在AVX2中高效实现log2(__ m256d)

在AVX2中高效实现log2(__ m256d)

C++
温温酱 2019-12-05 15:31:50
SVML __m256d _mm256_log2_pd (__m256d a)在除Intel以外的其他编译器上不可用,他们说它的性能在AMD处理器上受到限制。g ++-4.8中缺少 Internet上AVX日志内在函数(_mm256_log_ps)中引用的某些实现吗?和用于SSE和AVX的SIMD数学库,但是它们似乎比AVX2的SSE更多。还有一个Agner Fog的向量库,但是它是一个大型库,其中包含的内容远远超过了向量log2,因此从实现中很难仅找出向量log2操作的基本部分。那么有人能解释一下如何有效地log2()对4个double数字的向量进行运算吗?也就是说,它很喜欢__m256d _mm256_log2_pd (__m256d a),但是可用于其他编译器,并且对于AMD和Intel处理器都相当有效。编辑:在我当前的特定情况下,数字的概率在0到1之间,对数用于熵计算:所有i的和取反P[i]*log(P[i])。的浮点指数范围P[i]很大,因此数字可以接近0。我不确定精度,因此会考虑以30个尾数开头的任何解决方案,尤其是可调整的解决方案是首选。EDIT2:这是到目前为止我的实现,基于https://en.wikipedia.org/wiki/Logarithm#Power_series的 “更有效的系列” 。如何改善?(同时需要提高性能和准确性)到目前为止,我的实现每秒可以执行405 268 490次操作,而且直到第8位数字为止似乎都很精确。使用以下功能衡量性能:#include <chrono>#include <cmath>#include <cstdio>#include <immintrin.h>// ... Log2() implementation hereconst int64_t cnLogs = 100 * 1000 * 1000;void BenchmarkLog2Vect() {  __m256d sums = _mm256_setzero_pd();  auto start = std::chrono::high_resolution_clock::now();  for (int64_t i = 1; i <= cnLogs; i += 4) {    const __m256d x = _mm256_set_pd(double(i+3), double(i+2), double(i+1), double(i));    const __m256d logs = Log2(x);    sums = _mm256_add_pd(sums, logs);  }  auto elapsed = std::chrono::high_resolution_clock::now() - start;  double nSec = 1e-6 * std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();  double sum = sums.m256d_f64[0] + sums.m256d_f64[1] + sums.m256d_f64[2] + sums.m256d_f64[3];  printf("Vect Log2: %.3lf Ops/sec calculated %.3lf\n", cnLogs / nSec, sum);}与C ++和汇编语言中对数的结果相比,当前向量实现的速度是C + +的 4倍std::log2()和2.5倍std::log()。
查看完整描述

3 回答

  • 3 回答
  • 0 关注
  • 1285 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信