相关疑难解决方法(0)

我怎样才能优化这个计算?(x ^ a + y ^ a + z ^ a)^(1/a)

正如标题所示.我需要做这样的大量计算:

re = (x^a + y^a + z^a)^(1/a).
Run Code Online (Sandbox Code Playgroud)

其中{ x,y,z }> = 0.更具体地,a是正浮点常数,x,y,z是浮点数.这^是一个取幂运算符.

目前,我不想使用SIMD,但希望有其他一些技巧来加速它.

static void heavy_load(void) {
  static struct xyz_t {
    float x,y,z;
  };
  struct xyz_t xyzs[10000];
  float re[10000] = {.0f};
  const float a = 0.2;

  /* here fill xyzs using some random positive floating point values */

  for (i = 0; i < 10000; ++ i) {
    /* here is what we need to …
Run Code Online (Sandbox Code Playgroud)

c c++ math optimization

18
推荐指数
2
解决办法
1298
查看次数

当另一个公式似乎更有意义时,为什么基于表格的sin近似文献总是使用这个公式?

关于sin用表格计算基本函数的文献参考公式:

sin(x) = sin(Cn) * cos(h) + cos(Cn) * sin(h)
Run Code Online (Sandbox Code Playgroud)

其中x = Cn + h,Cn是针对其恒定sin(Cn)cos(Cn)已被预先计算并在表中可用的,并且,如果以下半乳糖的方法,Cn已被选择为使得两个sin(Cn)cos(Cn)密切由浮点数近似.数量h接近0.0.此公式的参考示例是本文(第7页).

我不明白为什么这是有道理的:cos(h)然而,它被计算,对于某些值,至少0.5 ULP可能是错误的h,并且因为它接近1.0,这似乎对结果的准确性有极大的影响.sin(x)以这种方式计算.

我不明白为什么不使用下面的公式:

sin(x) = sin(Cn) + (sin(Cn) * (cos(h) - 1.0) + cos(Cn) * sin(h))
Run Code Online (Sandbox Code Playgroud)

然后两个量(cos(h) - 1.0),并sin(h)可以用,很容易做出准确的,因为它们产生接近零的结果多项式来近似.为价值观sin(Cn) * (cos(h) - 1.0), cos(Cn) * sin(h)并为他们的总和仍然很小,其绝对精度,该总和表示,因此,加入这个量的少量ULPS表达sin(Cn)几乎是正确舍入. …

floating-point ieee-754 elementary-functions

15
推荐指数
2
解决办法
765
查看次数

-funsafe-math-optimizations中包含哪些优化?

GCC的手册页指出-funsafe-math-optimizations允许优化"(a)假设参数和结果有效,(b)可能违反IEEE或ANSI标准",但这不是很精确,是吗?

在这种情况下,什么可能是"无效"的论点?NaN的?Infinites?次归?负数到sqrt()

结果允许偏离IEEE或ANSI标准多远?它是"仅仅"像操作关联性和排序的东西,还是可能包括例如.与NaN的真实比较或与无限的不正确比较?可以存储变量进行重新四舍五入已被使用后(使得对变量 xy,(x == y) + (x == y)可以评估到1)?可以isinf()/ isnan()停止工作吗?

GCC开发人员是否遵循任何特定的系统或纪律来解决这些问题,或者答案在不同版本之间是否会有很大不同?

c floating-point optimization gcc

14
推荐指数
1
解决办法
3488
查看次数

算术表达式的优化 - 这种技术被称为什么?

与朋友的讨论导致以下实现:

>>> import dis
>>> i = lambda n: n*24*60*60
>>> dis.dis(i)
  1           0 LOAD_FAST                0 (n)
              3 LOAD_CONST               1 (24)
              6 BINARY_MULTIPLY
              7 LOAD_CONST               2 (60)
             10 BINARY_MULTIPLY
             11 LOAD_CONST               2 (60)
             14 BINARY_MULTIPLY
             15 RETURN_VALUE
>>> k = lambda n: 24*60*60*n
>>> dis.dis(k)
  1           0 LOAD_CONST               4 (86400)
              3 LOAD_FAST                0 (n)
              6 BINARY_MULTIPLY
              7 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

仅通过减少指令数量,第二个例子显然更有效.

我的问题是,这个优化是否有一个名称,为什么不在第一个例子中发生?

另外,我不确定这是否重复为什么GCC没有优化a*a*a*a*a*a到(a*a*a)*(a*a*a)?; 如果是,请进一步解释,因为它适用于Python.

python optimization arithmetic-expressions

14
推荐指数
1
解决办法
332
查看次数

每微秒1,000,000,000次计算?

好吧,我一直在和一位朋友谈论编译器和程序的优化,他建议这样n * 0.5做比n / 2.我说编译器会自动执行这种优化,所以我编写了一个小程序来查看n / 2和之间是否存在差异n * 0.5:

师:

#include <stdio.h>
#include <time.h>

int main(int argc, const char * argv[]) {
    int i, m;
    float n, s;
    clock_t t;

    m = 1000000000;
    t = clock();
    for(i = 0; i < m; i++) {
        n = i / 2;
    }
    s = (float)(clock() - t) / CLOCKS_PER_SEC;

    printf("n = i / 2: %d calculations took %f seconds (last calculation = %f)\n", m, …
Run Code Online (Sandbox Code Playgroud)

c c++ optimization compiler-optimization

12
推荐指数
3
解决办法
1573
查看次数

编译器会简化一次顺序执行几次的操作吗?

我这个问题已经很久了,但是却不知道在哪里看。如果某个操作多次编写,编译器会简化它还是运行完全相同的操作并获得完全相同的答案?

例如,在下文(i%3)*10中,多次重复类似c的伪代码。

for(int i=0; i<100; i++) {
    array[(i%3)*10] = someFunction((i%3)*10);
    int otherVar = (i%3)*10 + array[(i%3)*10];
    int lastVar = (i%3)*10 - otherVar;
    anotherFunction(lastVar);
}
Run Code Online (Sandbox Code Playgroud)

我了解变量在视觉上会更好,但会更快吗?是(i%3)*10计算每循环5次?

在某些情况下,我不知道使用变量还是仅保留原始操作更快。

编辑:在胜利10上使用gcc(MinGW.org GCC-8.2.0-3)8.2.0

c c++ optimization

10
推荐指数
1
解决办法
227
查看次数

为什么编译器使用-O3不能优化此C++成员函数?

下面声明norm的C++ vector类中的成员函数标记为const和(据我所知)不包含任何副作用.

template <unsigned int N>
struct vector {
  double v[N];

  double norm() const {
    double ret = 0;
    for (int i=0; i<N; ++i) {
      ret += v[i]*v[i];
    }
    return ret;
  }
};

double test(const vector<100>& x) {
  return x.norm() + x.norm();
}
Run Code Online (Sandbox Code Playgroud)

如果我打电话norm多次上const的实例vector(见test上面的函数)与GCC编译器(5.4版本)和优化开启(即-O3),那么编译器内联norm,但仍计算的结果norm多次,即使结果不应该改变.为什么编译器不优化第二次调用norm而只计算一次这个结果?这个答案似乎表明,如果编译器确定该norm函数没有任何副作用,编译器应该执行此优化.为什么在这种情况下不会发生这种情况?

请注意,我正在使用Compiler Explorer确定编译器生成的内容,并且下面给出了gcc版本5.4的程序集输出.clang编译器给出了类似的结果.另请注意,如果我使用gcc的编译器属性手动标记norm为使用const函数__attribute__((const)),那么第二次调用会根据需要进行优化,但我的问题是为什么gcc(和clang)不会自动执行此操作,因为norm定义可用?

test(vector<100u>&): …
Run Code Online (Sandbox Code Playgroud)

c++ optimization gcc clang++

9
推荐指数
1
解决办法
334
查看次数

x86可以独立或并行执行FPU操作吗?

我的老师声称处理器有时可以并行进行FPU操作.像这样:

float a = 3.14;
float b = 5.12;
float c;
float d = 3.02;
float e = 2.52;
float f;
c = a + b;
f = e + d;
Run Code Online (Sandbox Code Playgroud)

所以,正如我所听到的,上面的2个添加操作将比以下更快地执行:

float a = 3.14;
float b = 5.12;
float c;
float d = 3.02;
float e = 2.52;
float f;
c = a + b;
f = c + d;
Run Code Online (Sandbox Code Playgroud)

因为处理器必须等到c计算完成

我想验证这一点,所以我编写了一个执行第二件操作的函数,它通过检查时间戳计数器来测量时间:

flds    h # st(7)
flds    g # st(6)
flds    f # st(5)
flds    e …
Run Code Online (Sandbox Code Playgroud)

floating-point optimization x86 assembly fpu

9
推荐指数
1
解决办法
755
查看次数

clang的`-Ofast`选项在实践中有什么作用,尤其是与gcc的差异?

类似于问题gcc的ffast-math实际上做了什么?并且与Clang优化级别的SO问题有关,我想知道在实际条件下优化是做什么clang-Ofast,以及它们是否与gcc完全不同,或者这是否依赖于编译器依赖于硬件.

根据clang优化级别的公认答案,-Ofast增加了-O3优化:-fno-signed-zeros -freciprocal-math -ffp-contract=fast -menable-unsafe-fp-math -menable-no-nans -menable-no-infs.这似乎完全与浮点数学相关.但是这些优化对于像C++这样的事物来说意味着什么呢?像英特尔酷睿i7这样的CPU上的浮点数通用数学函数以及这些差异有多可靠?

例如,实际上:

该代码std::isnan(std::numeric_limits<float>::infinity() * 0)返回真正的我-O3.我相信这是符合IEEE数学标准的结果.

随着-Ofast不过,我得到一个错误的返回值.此外,该操作(std::numeric_limits<float>::infinity() * 0) == 0.0f返回true.

我不知道这是否与gcc中看到的相同.我不清楚结果如何依赖于结构,也不清楚编译器如何依赖它们,也不清楚是否存在任何适用的标准-Ofast.

如果有人可能会产生类似于一组单元测试代码公案来解决这个问题,那可能是理想的.我已经开始做这样的事情,但宁愿不重新发明轮子.

c++ floating-point x86-64 clang compiler-optimization

9
推荐指数
1
解决办法
2830
查看次数

如何加电?是否值得使用pow(x,2)?

进行乘法比在c ++中提高功率2更有效吗?

我正在尝试做最后的详细优化.编译器会将x*x与pow(x,2)相同吗?如果我没记错的话,乘法因某种原因更好,但也许在c ++ 11中并不重要.

谢谢

c++ c++11

7
推荐指数
3
解决办法
2万
查看次数