相关疑难解决方法(0)

在以下代码中没有"volatile"关键字时,编译器可以执行哪些优化?

以下是在运行Barrelfish操作系统时在Pandaboard上闪烁LED的一些代码.我的问题是,为什么不把LED的闪光灯,如果"挥发"关键字是从的定义中删除gpio_oegpio_dataout.

static volatile uint32_t *gpio_oe = (uint32_t *)(GPIO_BASE + 0x0134);
static volatile uint32_t *gpio_dataout = (uint32_t *)(GPIO_BASE + 0x013C);

void led_flash
{
    // Enable output
    *gpio_oe &= (~(1 << 8));

    // Toggle LED on and off till eternity
    while(true)
    {
      *gpio_dataout ^= (1 << 8);  // Set means LED on; Clear means LED off
       time_delay();  // To give blinking effect
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道如果变量的值可以通过程序外的源自发地改变,则需要使用volatile.但我在这里看不到这样的情况.编译器执行什么优化会使整个while循环闪烁LED无意义?这种优化背后的逻辑是什么,即.这种优化有意义的合法案例?

c embedded volatile

5
推荐指数
2
解决办法
485
查看次数

了解C中的volatile变量

我目前正在课堂上学习C,而且我对易变变量有一些困惑.我的教科书将它们定义为此.

易失性变量

volatile变量是由其他外部程序或同一程序随时更改的变量.语法如下. volatile int d;

正常变量和volatile变量之间究竟有什么区别?如果外部程序可以更改volatile变量,如何更改其他外部程序的值.

谢谢.

c variables volatile

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

写入视频内存(0xB8000)和易失性指针

我正在尝试用C编写自己的小内核,实际上我想写一个print函数来显示字符串.因此,我想写入视频内存(0xB8000).

所以,我试过这样的:

unsigned char *video = (unsigned char *)0xB8000;

*video = 'A';
Run Code Online (Sandbox Code Playgroud)

这实际上有效,但以下不是:

char x = 0;
unsigned char *video = (unsigned char *)(0xB8000 + x);

*video = 'A';
Run Code Online (Sandbox Code Playgroud)

经过一些研究,我认为原因可能是编译器的优化,OSDev给我解决方案:使用volatile关键字.所以我对这个关键字做了一些研究.OSDev建议:

char x = 0;
volatile unsigned char *video = (volatile unsigned char *)(0xB8000 + x);

*video = 'A';
Run Code Online (Sandbox Code Playgroud)

这样,它应该工作.编译器假定video指针指向的值可以更改,然后不进行优化.但是,如果以后我想改变它,比如:

video = (volatile unsigned char *)(video + 2);
Run Code Online (Sandbox Code Playgroud)

我不应该将指针定义为volatile,像unsigned char * volatile video?那么编译器知道地址可以改变吗?

c memory pointers volatile

3
推荐指数
1
解决办法
787
查看次数

为什么大多数c编译器都没有优化这种归零代码?

许多加密库包含类似于以下代码段的代码:

/* Implementation that should never be optimized out by the compiler */
static void optimize_proof_zeroize( void *v, size_t n )
{
    volatile unsigned char *p = v;
    while( n-- ) *p++ = 0;
}
Run Code Online (Sandbox Code Playgroud)

但是我的天真实现无法在优化编译器中存活:

/* Naive zeroization implementation */
static void naive_zeroize( unsigned char *c, size_t n)
{
    int i;
    for( i = 0; i < n; i++ )
       c[i] = 0;
}
Run Code Online (Sandbox Code Playgroud)

该代码用于在释放内存之前将敏感数据归零.由于缓冲区不再使用,优化编译器假设它们可以安全地从编译的代码中删除zeriozation.

是什么阻止了第一个实施的优化?

c security cryptography compiler-optimization

2
推荐指数
1
解决办法
178
查看次数

C 中的 vola 关键字

我正在Linux环境下为ARM编写程序。它\xe2\x80\x99s不是一个低级程序,比如说在应用程序级别。

\n

以下有什么区别?

\n

int iData;

\n

\n

volatile int iData;

\n

它有特定于硬件的影响吗?

\n

c volatile

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

在内存映射设备的情况下使用Volatile?

以下链接说"始终未访问设备寄存器的访问权限"

http://techpubs.sgi.com/library/dynaweb_docs/hdwr/SGI_Developer/books/DevDrvrO2_PG/sgi_html/ch01.html

我的问题是,当访问存储器映射的设备寄存器时,我们是否需要易失性?

c volatile embedded-linux

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

当中断例程中的变量发生变化时,确实需要volatile关键字

我正在使用nrf52微控制器(CORTEX 34F)处理器.我对主循环进行了变量检查,在主循环和定时器中断程序中都进行了修改.

  1. 主循环检查变量是否为真:

    • 执行条件代码

    • 将变量设置为false

  2. 定时器中断例程每10 ms将变量设置为true

没有volatile关键字,代码似乎不起作用,但当我将变量设置为volatile它似乎工作,但我不相信,因为:

  1. 首先我认为cortex M4f不包含数据缓存
  2. 第二:这个案例是handeld的编译器(arm keil)

任何答案,请;

if true执行正文代码2.列出项目

c embedded volatile interrupt-handling

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

使用volatile,禁用所有编译器优化

我们需要在关闭所有类型的编译器优化时使用volatile限定符,假设在启用编译器优化时需要它.

我阅读了有关SO Volatile和编译器优化的帖子,该文章说是,但没有给出任何需要它的特定用例.

有人可以指出仍然需要使用它们的情况,无论启用或禁用任何类型的优化.

c c++ volatile compiler-optimization

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

C中的“静态易失性”与“静态”对比“易失性”

static volatile组合使用变量说明符有什么区别?或者单独使用一个;喜欢staticvolatile在微控制器编程?

c variables specifier

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

了解C ++中的volatile关键字

我试图了解volatile关键字在C ++中的工作方式。

我看了一下“易失性”在C ++中可以防止哪些优化?。查看可接受的答案,看起来像volatile禁用了两种优化

  1. 防止编译器将值缓存在寄存器中。
  2. 在您的程序的POV中似乎不必要的时候,优化对该值的访问。

我在https://en.cppreference.com/w/cpp/language/as_if找到了类似的信息。

对易失性对象的访问(读取和写入)严格按照发生它们的表达式的语义来发生。特别是,它们不会相对于同一线程上的其他易失性访问而重新排序。

我编写了一个简单的C ++程序,该程序对数组中的所有值求和,以比较Plain ints和volatile int的行为。请注意,部分和不会不稳定。

数组由不合格的ints 组成。

int foo(const std::array<int, 4>& input)
{
    auto sum = 0xD;
    for (auto element : input)
    {
        sum += element;
    }
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

阵列由挥发性的int小号

int bar(const std::array<volatile int, 4>& input)
{
    auto sum = 0xD;
    for (auto element : input)
    {
        sum += element;
    }
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

当我查看生成的汇编代码时,仅在纯ints的情况下使用SSE寄存器。据我所知,使用SSE寄存器的代码既没有优化读取,也没有对读取进行重新排序。循环已展开,因此也没有分支。我能解释代码源为何不同的唯一原因是:在发生累积之前,可以对易失性读进行重新排序吗?显然,sum它不是挥发性的。如果这种重新排序不好,是否存在可以说明问题的情况/示例?

使用clang9生成的代码

foo(std::array<int, 4ul> …
Run Code Online (Sandbox Code Playgroud)

c++

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