gcc如何“并行化”代码?

时间:2014-03-25 04:17:34

标签: c gcc

我正在编写一个简单的系统调用函数,并遇到了一些我无法理解的现象。在下面的代码中,我使用变量“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;
}    

1 个答案:

答案 0 :(得分:4)

编译器在多线程意义上不会对代码进行并行化,如果可以将多个操作数打包到向量寄存器中,它会对代码进行“矢量化”,但这不是这里发生的事情。

我的猜测是对resched()的调用会改变proctab[currpid]的内容,因此当它返回到你的程序时,它现在有不同的值。只要您通过解除引用prptr来访问它,编译器就会安全,并且不会对该位置的内存内容做任何假设,因此它会从内存中生成负载。

但是,如果使用局部变量flag来“缓存”prptr->prhasmsgb的内容,则它不会从内存重新加载,并且您不执行案例1,2或者在您的交换机中执行{3},执行case 0案例defaultreturn error