Tag: 易失性

由main()修改并由ISR()访问的全局变量

这是我的c代码 char global_variable = 0; ISR(){ PORTA = global_variable; toggle_led;//to make sure that the interrupt is triggered } int main(){ while(1){ _delay_ms(500); gobal_variable++; PORTB = global_variable; } return 0; } 底线是我有一个由main函数修改的全局变量,并由main和ISR – 中断处理程序读取。 当main读取全局变量时,我得到期望的值,但在ISR中,我得到第一次分配给全局变量的值。 我知道这是一个优化问题,但我不明白是什么让编译器看到主要的正确值和ISR中的初始值 注意:当我在ISR中修改变量时,我在ISR中读取它,但在主要中我得到了初始值。

强制执行C语句的顺序?

我遇到了MS C编译器重新排序某些语句的问题,这些语句在multithreading上下文中非常重要,并且处于高优化级别。 我想知道如何在特定的地方强制订购,同时仍然使用高水平的优化。 (在低优化级别,此编译器不重新排序语句) 以下代码: ChunkT* plog2sizeChunk=… SET_BUSY(plog2sizeChunk->pPoolAndBusyFlag); // set “busy” bit on this chunk of storage x = plog2sizeChunk->pNext; 产生这个: 0040130F 8B 5A 08 mov ebx,dword ptr [edx+8] 00401312 83 22 FE and dword ptr [edx],0FFFFFFFEh 其中pPoolAndBusyFlag的写入由编译器重新排序,在pNext fetch 之后发生。 SET_BUSY本质上是 plog2sizeChunk->pPoolAndBusyFlag&=0xFFFFFFFeh; 我认为编译器已经正确地决定重新排序这些访问是正确的,因为它们是同一结构的两个独立成员,并且这种重新排序对单线程执行的结果没有影响: typedef struct chunk_tag{ unsigned pPoolAndBusyFlag; // Contains pointer to owning pool and […]

为什么线程同步不需要volatile关键字?

我读到volatile关键字不适合线程同步,事实上根本不需要它。 虽然我知道使用这个关键字是不够的,但我不明白为什么它完全没必要。 例如,假设我们有两个线程,线程A仅从共享变量读取,线程B仅写入共享变量。 通过例如pthreads互斥锁实现适当的同步。 IIUC,没有volatile关键字,编译器可能会查看线程A的代码并说:“这里的变量似乎没有被修改,但是我们有很多读取; 让我们只读一次,缓存值并优化掉所有后续读取。“它也可以查看线程B的代码并说:”我们在这里有很多写这个变量但没有读取; 因此,不需要写入值,因此我们可以优化所有写入。“ 两种优化都是不正确的。 和 都 挥发性会阻止一个人。 因此,我可能会得出结论,虽然volatile不足以同步线程,但仍然需要在线程之间共享任何变量。 (注意:我现在读到,实际上不需要volatile来防止写入错误;所以我没有想法如何防止这种不正确的优化) 我明白我错在这里。 但为什么?

如何强制在C中强制使用未被优化的未使用内存?

微控制器通常需要读取寄存器以清除某些状态条件。 在C中是否有可移植的方式来确保如果不使用数据则不会优化读取? 指向内存映射寄存器的指针是否足以声明为volatile? 换句话说,以下是否始终适用于标准兼容编译器? void func(void) { volatile unsigned int *REGISTER = (volatile unsigned int *) 0x12345678; *REGISTER; } 我知道处理这样的function会遇到编译器相关的问题。 所以,在这种情况下,我对便携式设备的定义有点松散。 我只是说它会尽可能广泛地使用最流行的工具链。

Delphi是否有任何与C的volatile变量等价的东西?

在C和C ++中,变量可以标记为volatile ,这意味着编译器不会对其进行优化,因为它可以在声明对象外部进行修改。 在Delphi编程中是否有相同的东西? 如果不是关键字,也许可以解决? 我的想法是使用绝对 ,但我不确定,这可能会引入其他副作用。

编译器有时可以缓存声明为volatile的变量

据我所知,编译器从不优化声明为volatile的变量。 但是,我有一个像这样声明的数组。 volatile long array[8]; 不同的线程读写它。 数组的元素仅由其中一个线程修改,并由任何其他线程读取。 但是,在某些情况下,我注意到即使我从一个线程修改一个元素,读取它的线程也不会注意到这个变化。 它继续读取相同的旧值,就好像编译器已将其缓存在某处。 但是编译器本身不应该缓存一个volatile变量,对吗? 那怎么会发生这种情况。 注意 :我没有使用volatile进行线程同步,所以请停止给我答案,比如使用锁或primefaces变量。 我知道volatile,atomic变量和互斥量之间的区别。 另请注意,该体系结构是x86,具有主动缓存一致性。 另外,在我认为变量被其他线程修改之后,我已经读了足够长的时间。 即使经过很长一段时间,阅读线程也看不到修改后的值。