为何 for只要 4 us

文章目录


https://www.arduino.cn/thread-12611-1-1.html
虽然 delayMicroseconds( ) 很好用,
可是常常有人喜欢用 for 来做 delay 延迟, 然后就发现怪怪的 !!

其实如下这句写法是等于没写的:

   for(int i=0; i < 32000; ++i);

如果你这样测量:

   unsigned long begt = micros( );
   for(int i=0; i < 32000; ++i);;;
   unsigned long endt = micros( );
   Serial.println(String("Run time=") + (endt-begt) );

你会发现印出 Run time=4
甚至有时还出现 Run time=0
怎会这样?
Arduino 的 CPU 有这么快吗?.. Arduino当然不可能那么快 !
阿那怎会只用 4 us ?

其实是因为 Compiler 很聪明, 发现你那 for Loop 根本没做事, 于是就很好心的帮你移除了, 等于没写!

所以, 如果发现 Run time=4 是因为 micros( ) 一定是四的倍数,
而这个 4 其实是因为执行了 begt = micros( ); 需要大约 2 us 的时间!
偶而会出现 0 则是刚好做 endt = micros( ); 正好还没变化, 但很可能快要变化了,
注意刚说了, micros( ) 每次变化就是多 4, 一定是四的倍数 !
如果控制 for 的 i 是全局变量, 则目前的 Arduino 就不会把空白的 for 移除掉!
为了方便好奇的网友测试,
以下我写了五个版本如下, 都只改一句, 大家可以测试看看

(1) for Loop 会被移除, Run time 大约 4
注意然在 setup( ) 与 loop( ) 之间有一个全局变量 int i;
但以下这 for(int i 的 i 当然不是外面在 void loop( ) 之前那个 i,
因为局部变量本来就可以与外面全局变量同名!
Compiler 发现这 for Loop 没事可做, 主动把整个 for Loop 全部移除!

void setup( ) {
  Serial.begin(9600);
  Serial.println("Test for Loop 3200 times,V.1, for(int i=...");
}
int i;
void loop( ) {
  unsigned long begt, endt;
  delay(258);
  begt=micros( );
  for(int i=0; i < 3200; ++i) {   // 16 clocks = 1 us
     // __asm__("NOP");  // 1 clock = 0.0625 us
  }
  endt = micros( );
  Serial.println(String("Run time =") + (endt-begt) +"us" );
  delay(3388);
} // loop(

(2) for Loop 正常执行, Run time 大约 1608us
注意这 for(int i 当然也不是外面在 void loop( ) 之前那个 i,
还有, 因为这 for Loop 内部有指令 “NOP”,
编译程序 Compiler 知道不可以把 for Loop 移除 !

void setup( ) {
  Serial.begin(9600);
  Serial.println("Test for Loop 3200 times,V.2, for(int i=... whth NOP");
}
int i;
void loop( ) {
  unsigned long begt, endt;
  delay(258);
  begt=micros( );
  for(int i=0; i < 3200; ++i) {
     __asm__("NOP");  // 1 clock = 0.0625 us
  }
  endt = micros( );
  Serial.println(String("Run time =") + (endt-begt) +"us" );
  delay(3388);
} // loop(

(3) for Loop 正常执行, Run time 至少 1400us (留给你测
注意以下这个 for( ) 的 i 是外面全局变量的 i

void setup( ) {
  Serial.begin(9600);
  Serial.println("Test for Loop 3200 times,V.3, for(i=...");
}
int i;
void loop( ) {
  unsigned long begt, endt;
  delay(258);
  begt=micros( );
  for(i=0; i < 3200; ++i) {  // i is Global
     // __asm__("NOP");  // 1 clock = 0.0625 us
  }
  endt = micros( );
  Serial.println(String("Run time =") + (endt-begt) +"us" );
  delay(3388);
} // loop(

//(4) for Loop 正常执行, Run time 至少 1600us (留给你测
注意以下这个 for( ) 的 i 也是外面全局变量的 i

void setup( ) {
  Serial.begin(9600);
  Serial.println("Test for Loop 3200 times,V.4, for(i=... whth NOP");
}
int i;
void loop( ) {
  unsigned long begt, endt;
  delay(258);
  begt=micros( );
  for(i=0; i < 3200; ++i) {
     __asm__("NOP");  // 1 clock = 0.0625 us
  }
  endt = micros( );
  Serial.println(String("Run time =") + (endt-begt) +"us" );
  delay(3388);
} // loop(

(5) for Loop 会被移除, Run time 大约 4
怎么会 ?!
for Loop 内不是有 kk = i; 要做事吗?
可是 Run time 只有 4 us, 你认为 for Loop 有存在吗?
不过, 很神奇的, kk 答案是正确的喔 (3199)!
可见 compiler 有多聪明了

void setup( ) {
  Serial.begin(9600);
  Serial.println("Test for Loop 3200 times,V.5, for(int i=...){kk=i;}");
}
int i, kk;
void loop( ) {
  unsigned long begt, endt;
  delay(258);
  begt=micros( );
  for(int i=0; i < 3200; ++i) {   // 16 clocks = 1 us
     kk = i;
  }
  endt = micros( );
  Serial.println(String("Run time =") + (endt-begt) +"us" );
  Serial.println("String("kk=") + kk + ",, should be 3199");
  delay(3388);
} // loop(
 

猜你喜欢

转载自blog.csdn.net/acktomas/article/details/88365204
今日推荐