当前位置: 首页 > 知识库问答 >
问题:

为什么GCC优化不适用于阵列?

邓卓
2023-03-14

这是一个使用ValArray的简单c程序:

#include <iostream>
#include <valarray>

int main() {
    using ratios_t = std::valarray<float>;

    ratios_t a{0.5, 1, 2};
    const auto& res ( ratios_t::value_type(256) / a );
    for(const auto& r : ratios_t{res})
        std::cout << r << " " << std::endl;
    return 0;  
}

如果我像这样编译并运行它:

g++ -O0 main.cpp && ./a.out

产出如预期:

512 256 128 

但是,如果我像这样编译和运行它:

g++ -O3 main.cpp && ./a.out

输出为:

0 0 0 

如果使用-O1优化参数,也会发生同样的情况。

GCC版本是(Archlinux最新版本):

$ g++ --version
g++ (GCC) 6.1.1 20160707

但是,如果我尝试叮当,两者

clang++ -std=gnu++14 -O0 main.cpp && ./a.out

clang++ -std=gnu++14 -O3 main.cpp && ./a.out

产生相同的正确结果:

512 256 128 

clang版本是:

$ clang++ --version
clang version 3.8.0 (tags/RELEASE_380/final)

我还尝试了在Debian上使用GCC 4.9.2,其中可执行文件会产生正确的结果。

这是GCC中可能存在的错误还是我做错了什么?有人能复制这个吗?

编辑:我设法在Mac OS上重现了GCC 6的Homebrew版本。

共有2个答案

耿俊
2023-03-14

这是粗心实现运算符/(constT

#include <iostream>
#include <valarray>

int main() {
    using ratios_t = std::valarray<float>;

    ratios_t a{0.5, 1, 2};
    float x = 256;
    const auto& res ( x / a );
    // x = 512;  //  <-- uncommenting this line affects the output
    for(const auto& r : ratios_t{res})
        std::cout << r << " ";
    return 0;
}

注释掉“x=512”行后,输出为

512 256 128 

取消对该行的注释,输出将更改为

1024 512 256 

由于在您的示例中,除法运算符的左侧参数是临时的,因此结果是未定义的。

使现代化

正如Jonathan Wakely正确指出的那样,在这个例子中,由于使用了auto,基于延迟评估的实现成为了一个问题。

谢旭
2023-03-14

valrayauto不能很好地混合。

这将创建一个临时对象,然后对其应用操作符/

const auto& res ( ratios_t::value_type(256) / a );

libstdcvalray使用表达式模板,以便运算符/返回一个轻量级对象,该对象引用原始参数并懒惰地计算它们。你使用const car

它将工作罚款,如果你这样做:

ratios_t res = ratios_t::value_type(256) / a;

更新:从今天起,GCC trunk将给出这个示例的预期结果。我已经修改了我们的valarray表达式模板,使其不易出错,因此创建悬挂引用更加困难(但仍然不是不可能)。新的实施应包括在明年的GCC 9中。

 类似资料:
  • 以下是我声称执行完全相同操作的两个函数: 从逻辑上讲,它们做同样的事情,为了100%确定,我编写了一个测试,通过它们运行了所有40亿个可能的输入,并且它们匹配。( 花费了2.9秒,使用< code>slow()花费了3.8秒。如果我使用一个全零的向量,这两个函数的性能没有明显的差别。 其他编译器: 主线clang 3.7及更高版本甚至对

  • https://godbolt.org/z/P97MaK 我玩的概念和预期d::is_equality_comparable工作矢量,但它没有。 编译错误在 内部失败,而不是在受概念保护的函数边界处失败。 这是错误还是预期行为?

  • 问题内容: 假设我有这个模型: 现在,如果我想高效地查看相册中的一部分照片。我这样做是这样的: 这只会执行两个查询,这正是我所期望的(一个查询得到相册,然后一个查询,例如“ SELECT * IN photos WHERE photoalbum_id IN()”。 一切都很棒。 但是,如果我这样做: 然后用!进行大量查询!我是在做错什么,还是django不够聪明,以至于它已经获取了所有照片并可以在

  • 我在更新链式lodash操作时遇到了这个问题,我不明白为什么会有不同的效果 我把范围缩小到用链子把一根forEach拴在一个lodash包装纸上 https://jsbin.com/wahokezeja/edit?js,控制台 这将抛出一个错误: “TypeError:\(…)。forEach(…)。groupBy不是一个函数 但是,当使用贴图链接时,效果很好 https://jsbin.com/

  • 我一直在收到com。谷歌。格森。JsonSyntaxException无法调用Gson。fromJson(),因此添加了一个捕获(异常)逻辑,但错误永远不会被捕获,而只是被抛出! 这是我所拥有的: 运行测试时,我得到“com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:应为BEGIN\u对象,但在第1行第1列路径$

  • 为什么JSF2/Facelet的ui:repeat不接受java。util。迭代器的值?可以在迭代器后面隐藏如此多的实现和内存节约,因为长度不需要知道,所以拥有它是非常有用的。但是相反,我需要将迭代器转换为列表,并抛弃所有优点,以便ui:repeat。 可能有阶段、时间或可序列化的原因,但我对可用文档的浏览并没有给出这些原因。我们还没有使这一不可能成为可能的科学吗?