compiler-optimization 相关问题

编译器优化涉及调整编译器以减少运行时或对象大小或两者。这可以使用编译器参数(即CFLAGS,LDFLAGS),编译器插件(例如DEHYDRA)或对编译器的直接修改(例如修改源代码)来实现。

限制限定符可以用来提示编译器外部函数不会修改你的内存吗?

作为我上一个问题的后续,请考虑以下代码: int f(int *p); 静态内联 int g0(int *p) { *p=0; f(空); // 可能会修改 *p 返回*p==0; } int caller0(int *q) { ret...

回答 1 投票 0

C 编译器有义务始终从内存中重新加载 const 值吗?

我的嵌入式 C 程序中有一个 const 变量。它在程序代码中用 0 进行定义和初始化。它通过链接描述文件放置在特殊的 ROM 区域中。可以更改特别内容...

回答 2 投票 0

是否有一种标准方法可以将表达式应用于数组中的多个元素,例如展开循环?

我一直想知道C++中是否有任何标准,允许您根据数组或其他一些预定义的数据集将静态表达式扩展为具有内部数据的N行代码...

回答 1 投票 0

为什么编译器不能优化 try-catch 块中的单个 throw 语句?

我只是在编译器资源管理器中玩一些 C++ 代码,并在编译简单的 try/catch 块时注意到一些意外的行为。以下两个片段都是用 gcc 编译的...

回答 1 投票 0

在C++中,在for循环之外使用“if”还是在for循环中使用“if”更有效

我正在用C++编写一个程序,我正在争论是否将“if”放在循环中。我想象做一次检查然后循环总体上会比常量 l 更有效......

回答 2 投票 0

每次迭代都会重新评估循环的条件吗? [重复]

我有一个如下所示的循环: 对于 (int i = 0; i < dim * dim; i++) Is the condition in a for loop re-evaluated on every loop? If so, would it be more efficient to do something like this?: ...

回答 3 投票 0

编译器会用一次调用替换循环中对 sqrt(2) 的调用吗?

双变量 = 0.; for(int i = 0; i < 1000000 ; i++) { var += sqrt(2.0); } std::cout << var << std::endl; Under MSVC2012, is it possible that under release with optimization turn ...

回答 2 投票 0

在循环中使用 string.length() 是否高效?

例如,假设字符串s是这样的: for(int x = 0; x < s.length(); x++) better than this?: int length = s.length(); for(int x = 0; x < length; x++)

回答 6 投票 0

为什么简单的 FP 循环不自动矢量化,并且比 SIMD 内在函数计算慢?

(为什么?)即使使用 -03 和 -march=native 进行编译,编译器也不使用 SIMD 指令来计算总和的简单循环吗? 考虑以下两个函数: 浮点数 sum_simd(const std::

回答 1 投票 0

(为什么?)simpe 循环不是矢量化的并且比 SIMD 计算慢吗?

(为什么?)即使使用 -03 和 -march=native 进行编译,编译器也不使用 SIMD 指令来计算总和的简单循环吗? 考虑以下两个函数: 浮点数 sum_simd(const std::

回答 1 投票 0

如果其中的所有代码都是同步的,V8 可以优化声明为异步的函数吗?

标题说明了一切。 同一件事的另一种说法是:如果异步函数不包含任何等待调用,V8 是否知道将其优化掉?

回答 1 投票 0

为什么空基类的大小可以为零?

基本上这是这个问题的后续.. 当我查看标准文档时,我发现了这个.. 在 9.3 班, 类类型的完整对象和成员子对象应具有非零大小。96...

回答 5 投票 0

GCC/CLANG 的编译器标志生成“BEXTR”指令(IA32 的 BMI1)

我正在寻找 GCC/CLANG 的编译器标志来生成 BEXTR 指令。 模板 constexpr Tunsigned bit_extract(Tunsigned uInput) { 重新...

回答 1 投票 0

为什么LLVM不对整数值进行范围分析?

我正在查看 Rust 编译器的输出程序集,发现它并没有像我预期的那样删除一些边界检查。经过额外的实验,我发现...

回答 1 投票 0

循环内if(循环不变)if语句的编译器优化

我在C中有一个这样的函数(在伪代码中,删除不重要的部分): int func(int s, int x, int* a, int* r) { 整数我; // 做一些事情 对于 (i=0;i 我在 C 中有一个这样的函数(在伪代码中,删除了不重要的部分): int func(int s, int x, int* a, int* r) { int i; // do some stuff for (i=0;i<a_really_big_int;++i) { if (s) r[i] = x ^ i; else r[i] = x ^ a[i]; // and maybe a couple other ways of computing r // that are equally fast individually } // do some other stuff } 这段代码被调用得太多,以至于这个循环实际上是代码中的速度瓶颈。我想知道一些事情: 由于 switch s 是函数中的常量,好的编译器会优化循环以使分支不会一直减慢速度吗? 如果没有,有什么好的方法来优化这段代码? ==== 这是包含更完整示例的更新: int func(int s, int start,int stop,int stride, double *x,double *b, int *a,int *flips,int *signs,int i_max, double *c) { int i,k,st; for (k=start; k<stop; k += stride) { b[k] = 0; for (i=0;i<i_max;++i) { /* this is the code in question */ if (s) st = k^flips[i]; else st = a[k]^flips[i]; /* done with code in question */ b[k] += x[st] * (__builtin_popcount(st & signs[i])%2 ? -c[i] : c[i]); } } } 编辑2: 如果有人好奇,我最终重构了代码并将整个内部 for 循环(带有 i_max)提升到外面,使 really_big_int 循环变得更加简单,并且希望易于矢量化! (并且还避免无数次执行一堆额外的逻辑) 优化代码的一个明显方法是将条件拉到循环之外: if (s) for (i=0;i<a_really_big_int;++i) { r[i] = x ^ i; } else for (i=0;i<a_really_big_int;++i) { r[i] = x ^ a[i]; } 精明的编译器也许能够将其更改为一次多个元素的 r[] 赋值。 微观优化 通常不值得花时间——审查更大的问题更有效。 然而,要进行微观优化,尝试各种方法,然后对它们进行分析以找到最好的方法,可以做出适度的改进。 除了 @wallyk 和 @kabanus 好的答案之外,一些简单的编译器还受益于以 0 结尾的循环。 // for (i=0;i<a_really_big_int;++i) { for (i=a_really_big_int; --i; ) { [编辑第二次优化] OP 添加了一个更完整的示例。问题之一是编译器无法假设 b 指向的内存与其他内存不重叠。这会阻止某些优化。 假设它们实际上不重叠,请在 restrict 上使用 b 来允许优化。 const 对于无法推断出这一点的较弱编译器也有帮助。 restrict 如果参考数据不重叠,其他人也可能受益。 // int func(int s, int start, int stop, int stride, double *x, // double *b, int *a, int *flips, // int *signs, int i_max, double *c) { int func(int s, int start, int stop, int stride, const double * restrict x, double * restrict b, const int * restrict a, const int * restrict flips, const int * restrict signs, int i_max, double *c) { 您的所有命令都是循环中的快速 O(1) 命令。 if 绝对是经过优化的,如果您的所有命令都是 r[i]=somethingquick 形式,那么您的 for+if 也是如此。您的问题可能归结为 big int 可以有多小? 快速 int main 从 INT_MIN 到 INT_MAX 求和为一个长变量,在 Windows 上的 Ubuntu 子系统上对我来说大约需要 10 秒。您的命令可能会将其乘以几倍,很快就会达到一分钟。最重要的是,如果您确实进行了大量迭代,这可能是无法避免的。 如果 r[i] 是独立计算的,这将是线程/多处理的经典用法。 编辑: 我认为 % 无论如何都会被编译器优化,但如果没有,请注意 x & 1 对于奇数/偶数检查要快得多。 假设x86_64,您可以确保指针对齐到16字节并使用intrinsics。如果它仅在具有 AVX2 的系统上运行,您可以使用 __mm256 变体(与 avx512* 类似) int func(int s, int x, const __m128i* restrict a, __m128i* restrict r) { size_t i = 0, max = a_really_big_int / 4; __m128i xv = _mm_set1_epi32(x); // do some stuff if (s) { __m128i iv = _mm_set_epi32(3,2,1,0); //or is it 0,1,2,3? __m128i four = _mm_set1_epi32(4); for ( ;i<max; ++i, iv=_mm_add_epi32(iv,four)) { r[i] = _mm_xor_si128(xv,iv); } }else{ /*not (s)*/ for (;i<max;++i){ r[i] = _mm_xor_si128(xv,a[i]); } } // do some other stuff } 虽然 if 语句将在任何像样的编译器上进行优化(除非你要求编译器不要优化),但我会考虑将优化写入(以防万一你在没有优化的情况下编译)。 此外,虽然编译器可能会优化“绝对”if语句,但我会考虑手动优化它,要么使用任何可用的内置函数,要么使用按位操作。 即 b[k] += x[st] * ( ((__builtin_popcount(st & signs[I]) & 1) * ((int)0xFFFFFFFFFFFFFFFF)) ^c[I] ); 这将取 popcount 的最后一位(1 == 奇数,0 == 偶数),将其乘以常量(如果是奇数则所有位为 1,如果为真则所有位为 0),然后对 c[I] 值进行异或(与 0-c[I] 或 ~(c[I]) 相同。 这将避免在第二个 absolute if 语句未优化的情况下发生指令跳转。 附注 我使用了一个 8 字节长的值,并通过将其转换为 int 来截断其长度。这是因为我不知道 int 在您的系统上可能有多长(在我的系统上是 4 个字节,即 0xFFFFFFFF)。

回答 5 投票 0

条件始终为真/假的 if 语句的编译器优化

我想到了条件和编译器。我正在为 Arduino 编写一个应用程序,因此我需要该应用程序尽可能快。 在我的代码中我有这个: #定义调试假 ......

回答 3 投票 0

编译器是否会删除条件始终为 false 的 if 语句?

我知道一些 C++ 中的元编程技术,用于在编译时计算常量。大多数情况下,元函数中的分支是通过三元运算符完成的,可以在编译时对其进行评估-

回答 2 投票 0

编译器是否会删除条件始终为 false 的 if 语句?

我知道一些 C++ 中的元编程技术,用于在编译时计算常量。大多数情况下,元函数中的分支是通过三元运算符完成的,可以在编译时对其进行评估-

回答 2 投票 0

编译器去虚拟化,是不是太智能了?

我写了这个简短的程序来看看去虚拟化是如何工作的。编译器应该能够推断出正确的类型: #包括 使用 std::cout; 使用 std::endl; 类基类 {

回答 1 投票 0

C++中final是用来优化的吗?

A类{ 民众: 虚空 f() = 0; }; B 类:公共 A { 民众: void f() 最终覆盖 { }; }; int main() { B* b = 新 B(); b->f(); } 在这种情况下,编译器是否重新...

回答 1 投票 0

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