我正在编写一个简单的系统调用函数,并遇到了一些我无法理解的现象。在下面的代码中,我使用变量“flag”来代替[1]和[2]中长期困扰的“prptr-> prhasmsgb”。我认为它不会造成任何差别,但事实证明,对prptr-> prhasmsgb = 0的第一次调用此函数将跳过if并输入switch()。这个错误是一致的,我想这可能与编译器(gcc)有关?此外,编译器(gcc)如何确定什么是独立的以及要并行化的内容?我对编译器一无所知,任何建议都会受到赞赏。谢谢!
ps:下面的代码几乎就是我原始代码中的代码,除了做某事。
prptr = &proctab[currpid]; /* prptr is a pointer, and below are supposed */
/* dealing with different prptr->prhasmsgb. */
/* prptr->prhasmsgb = (int){0,1,2,3} */
// int flag;
// flag = prptr->prhasmsgb; /* I used flag to replace prptr->prhasmsgb */
// /* if[1] & switch[2] are "paralleled" somehow */
/* case 0 is handled here */
if (prptr->prhasmsgb == 0) { /* [1] once was flag */
do something;
resched(); /* call reschedule */
}
switch (prptr->prhasmsgb) { /* [2] once was flag */
case 1:
do something;
return value;
case 2:
do something;
return value;
case 3:
do something;
return value;
case 0:
/* should never enter case 0 */
default:
return error;
}
答案 0 :(得分:4)
编译器在多线程意义上不会对代码进行并行化,如果可以将多个操作数打包到向量寄存器中,它会对代码进行“矢量化”,但这不是这里发生的事情。
我的猜测是对resched()
的调用会改变proctab[currpid]
的内容,因此当它返回到你的程序时,它现在有不同的值。只要您通过解除引用prptr
来访问它,编译器就会安全,并且不会对该位置的内存内容做任何假设,因此它会从内存中生成负载。
但是,如果使用局部变量flag
来“缓存”prptr->prhasmsgb
的内容,则它不会从内存重新加载,并且您不执行案例1,2或者在您的交换机中执行{3},执行case 0
案例default
和return error
。