C 减少While循环中的时钟周期计数以实现粒度

C 减少While循环中的时钟周期计数以实现粒度,c,performance,while-loop,msp430,C,Performance,While Loop,Msp430,对于MSP430处理器,我用C实现了一个while循环,目前看起来如下: register unsigned int sw\u loop\u count=0U; ... while(TACCL0和CCIE) { ++开关回路计数; } ... #pragma向量=时间向量 __中断无效计时器(无效) { //禁用定时器中断标志并启用。 TACCTL0&=~CCIFG; TACCTL0&=~CCIE; } 我将此循环用于校准目的,我认为其上下文对我的问题不太重要。我已经计算出循环的每个迭代,包括

对于MSP430处理器,我用C实现了一个
while
循环,目前看起来如下:

register unsigned int sw\u loop\u count=0U;
...
while(TACCL0和CCIE)
{
++开关回路计数;
}
...
#pragma向量=时间向量
__中断无效计时器(无效)
{
//禁用定时器中断标志并启用。
TACCTL0&=~CCIFG;
TACCTL0&=~CCIE;
}

我将此循环用于校准目的,我认为其上下文对我的问题不太重要。我已经计算出循环的每个迭代,包括检查
TACCL0&CCIE
需要11个时钟周期。出于粒度的目的,我真的希望这个数字尽可能低,如果可能的话,通过编程实现。我可能是个十足的白痴,但我想不出减少循环周期数的方法,所以任何建议都将不胜感激。我需要
sw\u loop\u count
值,不管怎样。

Hmm,在我发表评论后,我意识到你可能可以做些什么;-)在
while()
条件下,检查两个值。从外观上看,这两个值都必须定义为
volatile
,以便在每次使用时都能从内存中准备好

你能把这两个减为一个吗?让您的中断处理程序进行必要的比较,并设置一个您将在循环中检查的标志

或者你也可以用另一种方式来做,比如:

// signed and global (or you can pass it's address into your interrupt's routine)
volatile signed int sw_loop_count = 0;
然后是你的“测量”循环:

在你的中断程序中:

if(TACCL0 & CCIE)
{
  real_count = sw_loop_count; // save the value for future use before we destroy it
  sw_loop_count = -1; // this will turn into 0 in that while's pre-increment, ending the loop
}

奥托。。。引入
volatile
可能会受到内存访问的巨大影响,实际上可能会减慢
while()
循环。它确实完全取决于您的实际体系结构(具体到内存控制器和缓存控制器的类型),我仍然认为您最好通过汇编模式运行它,并查看编译器正在做什么。

嗯,在我发表评论后,我意识到您可能可以做些什么;-)在
while()
条件下,检查两个值。从外观上看,这两个值都必须定义为
volatile
,以便在每次使用时都能从内存中准备好

你能把这两个减为一个吗?让您的中断处理程序进行必要的比较,并设置一个您将在循环中检查的标志

或者你也可以用另一种方式来做,比如:

// signed and global (or you can pass it's address into your interrupt's routine)
volatile signed int sw_loop_count = 0;
然后是你的“测量”循环:

在你的中断程序中:

if(TACCL0 & CCIE)
{
  real_count = sw_loop_count; // save the value for future use before we destroy it
  sw_loop_count = -1; // this will turn into 0 in that while's pre-increment, ending the loop
}

奥托。。。引入
volatile
可能会受到内存访问的巨大影响,实际上可能会减慢
while()
循环。它确实完全取决于您的实际体系结构(具体取决于内存控制器和缓存控制器的类型)我仍然认为,您最好通过汇编程序模式运行它,并查看编译器正在执行的操作。

使用ASM输出在编译器中运行它,并查看编译器对您的循环执行了哪些操作。也许你可以在汇编程序层面上优化一些东西?在这种情况下,在处理完C代码后,您可以将和ASM块插入到C代码中。虽然在您的情况下,我怀疑TACCL0和CCIE都是易失性的,所以您必须确保每次都从内存(而不是CPU)读取它们,并且您几乎无法减少这些时间……您是否考虑过另一种测量性能的机制?也许在
while()
之前和之后抓取时间,只需将循环保持为空“{}”?这将减少执行增量指令的时间,并可能减少周期。这也可能由编译器优化…;-)@YePhIcK:TACCL0和CCIE不能是易失性的。TACCL0和CCIE是特殊的函数寄存器,而不是C变量。因为它们不在内存中,所以无法从内存中读取。它们必须从CPU读取,因为这是它们唯一应该在的地方。哦,那么我下面的答案并不完全正确:)但基本上是正确的-它应该(理论上)减少执行
while()的CPU周期数
loop使用ASM输出在编译器中运行此命令,并查看编译器对您的循环执行了哪些操作。也许你可以在汇编程序层面上优化一些东西?在这种情况下,在处理完C代码后,您可以将和ASM块插入到C代码中。虽然在您的情况下,我怀疑TACCL0和CCIE都是易失性的,所以您必须确保每次都从内存(而不是CPU)读取它们,并且您几乎无法减少这些时间……您是否考虑过另一种测量性能的机制?也许在
while()
之前和之后抓取时间,只需将循环保持为空“{}”?这将减少执行增量指令的时间,并可能减少周期。这也可能由编译器优化…;-)@YePhIcK:TACCL0和CCIE不能是易失性的。TACCL0和CCIE是特殊的函数寄存器,而不是C变量。因为它们不在内存中,所以无法从内存中读取。它们必须从CPU读取,因为这是它们唯一应该在的地方。哦,那么我下面的答案并不完全正确:)但基本上是正确的-它应该(理论上)减少执行
while()
循环的CPU周期数我在中断例程中使用的时间实际上不太重要,现在我已经得到了我需要的值,所以这可能真的有效。我已经看过了反汇编,它显示递增和跳跃的时钟周期是6,所以这将给我带来相当大的节省。实际上,我目前还没有得到太多的优化,所以这可以为我节省更多。我明天会试试,然后再给你回复,谢谢。我在中断程序中使用的时间实际上并没有太大关系,就像我所说的那样