首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重写SVML的函数调用

重写SVML的函数调用
EN

Stack Overflow用户
提问于 2017-03-07 09:41:59
回答 1查看 380关注 0票数 2

Xeon骑士登陆核心有一个快速exp2指令vexp2pd (内禀_mm512_exp2a23_pd).Intel C++编译器可以使用编译器附带的短向量数学库对exp函数进行矢量化。具体来说,它调用函数__svml_exp8

但是,当我通过调试器时,我没有看到__svml_exp8使用vexp2pd指令。它是一种复杂的功能,许多FMA手术。我知道vexp2pdexp更不准确,但是如果我使用-fp-model fast=1 (默认的)或fp-model fast=2,我希望编译器使用这个指令,但它不使用。

我有两个问题。

  1. 有没有办法让编译器使用vexp2pd
  2. 如何安全地覆盖对__svml_exp8的调用

至于第二个问题,这是我到目前为止所做的。

代码语言:javascript
复制
//exp(x) = exp2(log2(e)*x)  
extern "C" __m512d __svml_exp8(__m512d x) {        
    return _mm512_exp2a23_pd(_mm512_mul_pd(_mm512_set1_pd(M_LOG2E), x));
}

这里安全吗?是否有更好的解决方案,例如嵌入函数的解决方案?下面的测试代码中的比我不覆盖的速度快3倍。

代码语言:javascript
复制
//https://godbolt.org/g/adI11c
//icpc -O3 -xMIC-AVX512 foo.cpp
#include <math.h>
#include <stdio.h>
#include <x86intrin.h>

extern "C" __m512d __svml_exp8(__m512d x) {
  //exp(x) = exp2(log2(e)*x)  
  return _mm512_exp2a23_pd(_mm512_mul_pd(_mm512_set1_pd(M_LOG2E), x));
}

void foo(double * __restrict x, double * __restrict y) {
  __assume_aligned(x, 64);
  __assume_aligned(y, 64);
  for(int i=0; i<1024; i++) y[i] = exp(x[i]);
}

int main(void) {
  double x[1024], y[1024];
  for(int i=0; i<1024; i++) x[i] = 1.0*i;
  for(int r=0; r<1000000; r++) foo(x,y);
  double sum=0;
  //for(int i=0; i<1024; i++) sum+=y[i];
  for(int i=0; i<8; i++) printf("%f ", y[i]); puts("");
  //printf("%lf",sum);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-09 22:24:13

ICC将生成vexp2pd,但只有在目标-fimf*交换机指定的非常宽松的数学要求下才能生成。

代码语言:javascript
复制
#include <math.h>

void vfoo(int n, double * a, double * r)
{
    int i;
    #pragma simd
    for ( i = 0; i < n; i++ )
    {
        r[i] = exp(a[i]);
    }
}

例如用-xMIC-AVX512 512-fimf域编译-排除=1-fimf-精度-位=22

代码语言:javascript
复制
..B1.12:
        vmovups   (%rsi,%rax,8), %zmm0
        vmulpd    .L_2il0floatpacket.2(%rip){1to8}, %zmm0, %zmm1
        vexp2pd   %zmm1, %zmm2
        vmovupd   %zmm2, (%rcx,%rax,8)
        addq      $8, %rax
        cmpq      %r8, %rax
        jb        ..B1.12

请务必理解准确性的含义,因为不仅最终结果只有大约22位准确,而且vexp2pd也会将任何非规范化结果刷新为零,而不管MXCSR中设置的FTZ/DAZ位如何。

对于第二个问题:“我如何安全地覆盖对__svml_exp8的调用?”您的方法通常是不安全的。SVML例程是Intel编译器的内部程序,并且依赖于自定义调用约定,因此具有相同名称的通用例程可能会比库例程更多地破坏寄存器,并且您可能最终会陷入难以调试的ABI错配。

提供您自己的向量函数的一个更好的方法是使用#实用化omp声明simd,例如请参阅https://software.intel.com/en-us/node/524514,如果更喜欢使用本质编码,请参见https://software.intel.com/en-us/node/523350。只是不要试图覆盖标准的数学名称,否则就会出错。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42644794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档