相关疑难解决方法(0)

在C++中强制执行语句顺序

假设我有一些我想以固定顺序执行的语句.我想使用优化级别为2的g ++,因此可以重新排序某些语句.有什么工具可以强制执行某些语句排序?

请考虑以下示例.

using Clock = std::chrono::high_resolution_clock;

auto t1 = Clock::now(); // Statement 1
foo();                  // Statement 2
auto t2 = Clock::now(); // Statement 3

auto elapsedTime = t2 - t1;
Run Code Online (Sandbox Code Playgroud)

在这个例子中,重要的是语句1-3以给定的顺序执行.但是,编译器不能认为语句2独立于1和3并执行如下代码?

using Clock=std::chrono::high_resolution_clock;

foo();                  // Statement 2
auto t1 = Clock::now(); // Statement 1
auto t2 = Clock::now(); // Statement 3

auto elapsedTime = t2 - t1;
Run Code Online (Sandbox Code Playgroud)

c++ operator-precedence c++11

103
推荐指数
4
解决办法
1万
查看次数

如何防止gcc优化C中的一些语句?

为了使页面变脏(打开页表项中的脏位),我触摸页面的第一个字节,如下所示:

pageptr[0] = pageptr[0];
Run Code Online (Sandbox Code Playgroud)

但在实践中,gcc将忽略死店淘汰的陈述.为了防止gcc优化它,我重新编写语句如下:

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;
Run Code Online (Sandbox Code Playgroud)

似乎这个伎俩有效,但有点难看.我想知道是否有任何指令或语法具有相同的效果?而且我不想使用-O0旗帜,因为它也会带来很大的性能损失.

c gcc

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

什么是"代表; nop;" 在x86汇编中意味着什么?它与"暂停"指令相同吗?

  • 什么rep; nop意思?
  • 它和pause指令一样吗?
  • 它是否与rep nop(没有分号)相同?
  • 这个简单的nop指令有什么区别?
  • 它在AMD和英特尔处理器上的表现是否不同?
  • (奖金)这些说明的官方文件在哪里?

这个问题的动机

另一个问题的评论中进行一些讨论后,我意识到我不知道rep; nop;x86(或x86-64)汇编中的含义.而且我也无法在网上找到一个好的解释.

我知道这rep是一个前缀,意味着"重复下一个指令cx时间"(或至少它是,在旧的16位x86汇编中).根据这一维基百科汇总表,似乎rep只能与使用movs,stos,cmps,lods,scas(但也许是对新的处理器去掉这个限制).因此,我认为rep nop(没有分号)将重复nop操作cx时间.

然而,经过进一步搜索,我更加困惑.它似乎rep; noppause 映射到完全相同的操作码,并且pause有一些不同的行为nop.2005年的一些旧邮件说不同的东西:

  • "尽量不要燃烧太多的力量"
  • "它只相当于'nop',仅使用2字节编码."
  • "这对英特尔来说是神奇的.它就像'nop但是让其他HT兄弟跑了'"
  • "这是暂停英特尔和Athlon的快速填充"

有了这些不同的意见,我无法理解正确的含义.

它正在Linux内核中使用(在i386x86_64上)以及此注释:/* REP …

cpu x86 assembly x86-64 machine-code

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

asm,asm volatile和clobbering memory之间的区别

在实现无锁数据结构和时序代码时,通常需要抑制编译器的优化.通常人们在clobber列表中使用asm volatilewith memory,但你有时会看到asm volatile或只是一个简单的asm破坏性记忆.

这些不同的陈述对代码生成有什么影响(特别是在GCC中,因为它不太可能是可移植的)?

仅供参考,这些是有趣的变化:

asm ("");   // presumably this has no effect on code generation
asm volatile ("");
asm ("" ::: "memory");
asm volatile ("" ::: "memory");
Run Code Online (Sandbox Code Playgroud)

c gcc inline-assembly

62
推荐指数
2
解决办法
4万
查看次数

C/C++中的无限循环

有几种可能性来进行无限循环,这里有一些我会选择:

  • for(;;) {}
  • while(1) {}/while(true) {}
  • do {} while(1)/do {} while(true)

是否有某种形式应该选择?现代编译器是否会在中间和最后一个语句之间产生影响,或者它是否意识到它是一个无限循环并完全跳过检查部分?

编辑:因为已经提到我忘记了goto,但这是因为我根本不喜欢它作为一个命令.

Edit2:我对从kernel.org获取的最新版本做了一些grep.我确实看起来随着时间的推移没有太大变化(至少在内核中) 在此输入图像描述

c c++ loops infinite-loop

57
推荐指数
7
解决办法
9万
查看次数

有没有办法告诉GCC不优化特定的代码?

我正在开发一个依赖于编译器优化的项目,但我需要一些不被GCC优化的代码.这可能吗?

optimization gcc

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

如何防止g ++优化由可由IRQ更改的变量控制的循环?

考虑以下代码:

unsigned global;
while(global);
Run Code Online (Sandbox Code Playgroud)

global在由IRQ调用的函数中被修改.但是,g ++删除了"is-not-zero"测试,并将while循环转换为无限循环.

禁用编译器优化可以解决问题,但C++是否为它提供了语言结构?

c++ gcc g++ irq

22
推荐指数
2
解决办法
3891
查看次数

如何不优化远离 - 愚蠢功能的机制

我正在寻找一种编程技术,确保用于基准测试的变量(没有可观察到的副作用)不会被编译器优化掉

提供了一些信息,但我最终使用了愚蠢和以下功能

/**
 * Call doNotOptimizeAway(var) against variables that you use for
 * benchmarking but otherwise are useless. The compiler tends to do a
 * good job at eliminating unused variables, and this function fools
 * it into thinking var is in fact needed.
 */
#ifdef _MSC_VER

#pragma optimize("", off)

template <class T>
void doNotOptimizeAway(T&& datum) {
  datum = datum;
}

#pragma optimize("", on)

#else
template <class T>
void doNotOptimizeAway(T&& datum) {
  asm volatile("" : "+r" (datum)); …
Run Code Online (Sandbox Code Playgroud)

c++ benchmarking assembly c++11 c++14

19
推荐指数
1
解决办法
1853
查看次数

防止gcc删除未使用的变量

在我们的源文件中,我们通常有一个类似的版本字符串:

static const char srcvers[] = "VERSION/foo.c/1.01/09.04.15";
Run Code Online (Sandbox Code Playgroud)

当该字符串未被优化时,它在某些情况下非常有用,因为可以通过简单地调用来确定链接到可执行文件的每个源文件的版本strings a.out | grep VERSION.

不幸的是,它 gcc优化(使用'-O').所以我的问题是,是否有一种简单的方法(编译器开关会很棒)使gcc保持该变量(其名称始终相同)而不关闭任何其他优化.

编辑

在我看来,这个问题与那个不同的是,我希望找到一个解决方案,我不必触及成千上万的源文件.

c gcc

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

允许 struct 字段溢出到下一个字段

考虑以下简单示例:

struct __attribute__ ((__packed__)) {
 int code[1];
 int place_holder[100];
} s;

void test(int n)
{
 int i;

 for (i = 0; i < n; i++) {
  s.code[i] = 1;
 }
}
Run Code Online (Sandbox Code Playgroud)

for 循环正在写入code大小为 1 的字段 。之后的下一个字段codeplace_holder
我希望在 的情况下n > 1,写入code数组会溢出并1写入place_holder.

但是,在使用-O2(在 gcc 4.9.4 上但也可能在其他版本上)进行编译时,会发生一些有趣的事情。
编译器识别出代码可能溢出数组code,并将循环展开限制为 1 次迭代

很容易看出,在编译-fdump-tree-all和查看最后一个树传递(“t.optimized”)时:


;; Function test (test, funcdef_no=0, decl_uid=1366, symbol_order=1)

Removing basic block …
Run Code Online (Sandbox Code Playgroud)

c gcc struct compiler-optimization loop-unrolling

8
推荐指数
2
解决办法
538
查看次数