g++ 相关问题

g ++是GNU编译器集合(gcc)的C ++前端。

OpenMP for 循环比串行代码花费更多时间

我尝试使用 OpenMP 并行化代码片段,结果发现使用 OpenMP 需要 25 倍的时间才能完成程序。有什么不对的吗?我该如何优化它? #包括 我尝试使用 OpenMP 并行化代码片段,结果发现使用 OpenMP 需要 25X 时间才能完成程序。有什么不对的吗?我该如何优化它? #include <iostream> #include <cmath> #include <random> #include <chrono> #include <cstdlib> #include <omp.h> using namespace std; int main() { unsigned long long black_square = 1, digit_square = 13; //auto n = ((black_square)<<11) * static_cast<unsigned long long>(pow(digit_square,10)); auto n = static_cast<unsigned long long>(1e9); srand(0); int tmp = 0; std::random_device rd; // Will be used to obtain a seed for the random number engine std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() std::uniform_int_distribution<> distrib(1, 6); auto tStart = std::chrono::high_resolution_clock::now(); //#pragma omp parallel for schedule(static) reduction(+:tmp) #pragma omp parallel for schedule(static) reduction(+:tmp) num_threads(8) for (unsigned long long i=0; i<n; i++) tmp = (tmp+(5==rand()%6))%static_cast<int>(1e9); //for (unsigned long long i=0; i<n; i++) tmp = (tmp+(5==distrib(gen)))%static_cast<int>(1e9); tmp%=static_cast<int>(1e9); auto tEnd = std::chrono::high_resolution_clock::now(); cout << tmp << " obtained after " << n << " iterations in " << (tEnd-tStart).count()/1e9 << "s." << endl; return 0; } 代码由g++ -o a.out -O3 -std=c++11 -fopenmp tmp.cpp编译,其中g++的版本为8.5.0 20210514。操作系统是RHEL8.9,有20个Intel Xeon CPUs at 2.593GHz。 串行代码平均运行时间为7.4s,而并行代码平均运行时间为180s。选项 -O3、-O2、-O1 具有相似的结果。随机生成器mt19937可以显着缩小性能差距,但并行代码仍然比串行版本慢得多。增加或减少 n 也会导致类似的结果。 rand()函数不需要是线程安全的。因此,像您所做的那样同时从多个线程调用它是不安全的 glibc 的 rand() 版本是线程安全的,但它是通过将整个函数包装在互斥体中来实现的。因此一次只有一个线程可以调用 rand()。由于在 rand 调用之外,您的代码执行的操作非常少,几乎所有执行时间都将在 rand() 内。 所以并行版本并不是真正的并行。每次调用 rand() 时,每个线程轮流一次执行一个。所以它比单线程没有优势。但实际上更糟糕的是,因为线程必须争夺谁获得互斥锁,在每次调用后唤醒和睡眠,并在每个 CPU 核心的缓存之间移动 PRNG 状态。所以比单线程差很多。 您应该做的是创建多个 PRNG 实例。有一个 gen 对象数组,每个线程一个。每个线程应该使用自己的 PRNG。确保每个对象在内存中相距足够远,不会共享缓存行,因此 PRNG 状态不需要在 CPU 缓存之间移动。

回答 1 投票 0

Mingw32 std::isnan 与 -ffast-math

我正在使用 -ffast-math 选项编译以下代码: #包括 #包括 #包括 int main() { std::cout << std::isnan(std::numeric_...

回答 2 投票 0

R中由于文件路径指定错误导致的c++/g++包编译问题的解决方案

当我尝试安装从源代码(特别是 rstan)编译的软件包时,我在 R/RStudio 中遇到了两次问题,因为 R 始终在错误的位置查找 g++ 编译器。

回答 1 投票 0

又一个警告:“<anonymous>”可能会在未初始化的情况下使用

我看到了许多关于同一警告的其他问题,但我的代码似乎不同。 而且,总的来说,我只能通过 -Os 选项才能得到这个。 #包括 使用命名空间 std ; 模板 我看到了许多其他关于同一警告的问题,但我的代码似乎不同。 而且,总的来说,我只能通过 -Os 选项才能得到这个。 #include <iostream> using namespace std ; template <class TYPE,class FUNC> struct AutoDestruct { const TYPE & var ; FUNC func ; AutoDestruct ( const TYPE & v , FUNC f ) : var(v),func(f) {} ~AutoDestruct () { func(var) ;} }; class Dictionary { public: Dictionary & wipe () { cout << "Dictionary.wipe()\n" ; return *this ;} }; static void wipe_dict ( Dictionary * dict ) { dict->wipe() ;} typedef AutoDestruct<Dictionary*,void(*)(Dictionary*)> AutoWipe ; int main () { cout << "enter main function " << __DATE__ << " " << __TIME__ << endl ; Dictionary headers ; AutoWipe auto_wipe( &headers,wipe_dict ) ; cout << "exit main function\n" ; } 命令行是: g++ -std=c++11 -Os -Wall -Wextra test.cpp && ./a.out N.B.:如果我删除 -Os 选项,我不会收到任何警告。 输出是: test.cpp: In function ‘int main()’: test.cpp:9:48: warning: ‘<anonymous>’ may be used uninitialized [-Wmaybe-uninitialized] 9 | ~AutoDestruct () { func(var) ;} | ^~~~ test.cpp:25:46: note: ‘<anonymous>’ was declared here 25 | AutoWipe auto_wipe( &headers,wipe_dict ) ; | ^ enter main function May 13 2024 20:14:01 exit main function Dictionary.wipe() 编译器是: g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 这是我真实代码的一个非常简单的摘录,只是为了暴露警告。 但请注意,在我的真实代码中,执行 auto_wipe 时,我收到警告 AND 段错误! 知道警告+段错误原因吗? 预先感谢! 我认为走一小段路是值得的,因为我想我不是唯一一个最初误读你的代码的人。我认为我正在阅读的代码是这样的: #include <iostream> using namespace std; template <class TYPE,class FUNC> struct AutoDestruct { TYPE& var ; FUNC func ; AutoDestruct(TYPE& v, FUNC f ) : var(v),func(f) {} ~AutoDestruct () { func(var) ;} }; struct Dictionary { Dictionary & wipe () { cout << "Dictionary.wipe()\n" ; return *this ;} }; static void wipe_dict ( Dictionary & dict ) { dict.wipe() ;} typedef AutoDestruct<Dictionary,void(*)(Dictionary&)> AutoWipe ; int main () { Dictionary headers ; AutoWipe auto_wipe( headers,wipe_dict) ; } auto_wipe 存储对 headers 的引用,当调用它的析构函数时,它会调用 headers.wipe();。然后调用 headers 析构函数,一切都很好。 虽然在你的代码中,这里: AutoWipe auto_wipe( &headers,wipe_dict ) ; 您的 auto_wipe 存储对临时 &headers 的引用。当 auto_wipe 的析构函数被调用时,对象 headers 当然仍然存储在相同的内存地址中。然而,由 &headers 产生的临时指针早已消失,并且该成员是一个悬空引用。您可以按照注释中的建议复制指针,也可以按照上面的方式存储对实际对象的引用。 TL;DR:编译器发出警告是正确的。您存储一个悬空引用。使用地址消毒剂会突出这个问题。

回答 1 投票 0

链接低版本编译器编译的动态库有什么潜在问题吗?

这样的情况下有没有潜在的问题? 我的项目使用g++11.4编译,而我无法控制的所需动态库则使用g++8.2编译。

回答 1 投票 0

clang:错误:未知参数:'-fno-leading-underscore'

我正在尝试使用 -fno-leading-underscore 选项编译我的 .cpp,但它会引发错误: clang:错误:未知参数:'-fno-leading-underscore' g++ -m32 -fno-use-cxa-atexit -nostdlib -fno-

回答 2 投票 0

std::println/print 在 Winlibs MinGW 中不起作用(gcc 14.1)

我正在 GCC 14.1 中测试新的 库,并尝试使用 std::println() 编译一个程序,结果却收到了这个消息(为了隐私,我已从 Users 目录中删除了我的名字...

回答 1 投票 0

std::println/print 在 gcc 14.1 中不起作用

我正在 GCC 14.1 中测试新的 库,并尝试使用 std::println() 编译一个程序,结果却收到了这个消息(为了隐私,我已从 Users 目录中删除了我的名字...

回答 1 投票 0

编译器不会警告“int in bool context”

在我的项目中,我将许多函数的返回值从布尔值更改为枚举值。 问题出在整合上。编译器不会警告我错误使用这些函数。 我正在使用...

回答 1 投票 0

为什么当 enum 或 int 值作为 bool 函数参数传递时 GCC 不发出警告?

我有以下代码: 类型定义枚举 { FOO, 酒吧, 巴兹 } 脚; 静态无效 afunc(bool is_it_on) { /* 完成工作 */ } int 主函数(无效) { afunc(BAZ); 返回0; } 编译这个...

回答 1 投票 0

在 x64 架构上使用 G++ 编译 FMOD

我一直在努力在 VS Code 上使用 FMOD 编译我的程序。我对使用 Visual Studio 默认编译器以外的其他东西进行编译还很陌生,因此与其他文件格式的链接已经......

回答 1 投票 0

G++ 4.4“未初始化”变量

如果操作系统与此事完全相关,我正在 Ubuntu 10.10(64 位)上使用 g++。 我看到了一些奇怪的东西,所以我决定检查一下,出于某种原因这段代码 #包括 int main()...

回答 2 投票 0

开放人工智能可以弄清楚如何在其他事情上训练他们的痛苦关系

问题被删除,因为我确信开放人工智能在没有我帮助的情况下也能很好地吞噬世界。

回答 2 投票 0

GCC v12.1 关于串行编译的警告

我今天(2022 年 5 月 12 日)升级了整个 arch Linux 系统。 gcc 也从 v11.2 升级到 v12.1。我尝试使用 g++(gcc 编译器集合的一部分)通过

回答 1 投票 0

警告:“auto”类型说明符是 C++11 扩展

我有一个非常简单的C++代码语句auto a = 12;。 当我在 Linux 中使用 -std=c++98 选项用 g++ 编译它时,我收到了预期的错误: 错误:“a”没有命名类型 但是……

回答 2 投票 0

g++ 版本标志未正确切换 c++ 版本

我过去通常使用c++11,并使用“-std=c++11”标志进行手动编译和生成文件来执行此操作。现在我想使用文件系统库,这需要c++1...

回答 1 投票 0

为什么我不能对 std::ranges::to<std::vector>() 的结果使用下标运算符?

为什么我不能在 std::ranges::tostd::vector() 的结果上使用下标运算符,或者更好地不使用下标运算符,解决方案是什么? 顺便说一句,我正在尝试使用 G++ 主干。 #包括 #

回答 1 投票 0

g++ 优化了发布版本中对 INT_MIN 的检查

我遇到了一个问题,g++ 优化了一些它不应该有的东西。我将问题简化为以下示例: 我有一个带有函数 bool my_magic_function(int* x) 的静态库,其中

回答 1 投票 0

可以在Ubuntu 16.04中使用Gcc 11和G++ 11吗?

我使用的是 Ubuntu 16.04,我只能将 Gcc 和 G++ 编译器更新到 9.4.0 版本,但我需要使用 Gcc 和 G++ 11。我该怎么做? 我希望解决之前有关更新的问题...

回答 1 投票 0

collect2.exe:错误:ld 返回 1 退出状态

有一个带有 SFML 的简单 C++ 脚本。当我尝试编译它时,编译器出现一些错误。 请注意,代码编辑器中不会显示与脚本相关的错误。 脚本: #包括<...

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.