Peterson的算法对各种优化标志的行为

我想检查gcc和icc的行为以获得各种优化选项。 采用彼得森的2线程互斥算法。 如果交换了lock方法中第a行和第b行(在注释中)的执行顺序,则此算法可能会失败。 使用icc或带有-O0标志的gcc进行编译会产生正确的结果。 使用带有-O3标志的icc进行编译会产生不正确的结果。 使用带有-O3标志的gcc进行编译不会产生任何结果。 程序挂起。 所以我的猜测是-O3标志,gcc和icc都优化了锁定方法,并假设线a和线b之间没有依赖关系。 因此两者产生了错误的结果 这样的依赖很难让编译器找到,所以有没有办法(像ivdep这样的编译器)告诉编译器特定代码块中的依赖关系,这样我们仍然可以在代码的其他部分使用-O3标志

锁定方法:

void lock(int me) { int other; other = 1-me; flag[me] = 1; //Line a victim = me; //Line b while(flag[other]==1 && victim == me) { } } 

如果交换了行a和行b的执行顺序,则为MUTEX违规的示例:

 T0 0 sets victim=0 T1 1 sets victim=1 T2 1 sets flag[1]=1 T3 1 checks flag[0]. flag[0] not yet set. T4 1 enters CS T5 0 sets flag[0]=1 and checks flag[1]. It is set but victim=1. T6 0 also enters cs 

完整代码:

 #include #include #include #include #include int flag[2]; int victim; int sharedCounter=0; void lock(int me) { int other; other = 1-me; flag[me] = 1; victim = me; while(flag[other]==1 && victim == me) { } } void unlock(int me) { flag[me]=0; } void *peterson(void *ptr) { int tId,i; tId = (int ) (intptr_t) ptr; for(i=0;i<200;i++) { lock(tId); sharedCounter++; printf("%d\t",sharedCounter); sleep(1/10); unlock(tId); } } main() { int i; for(i=0;i<2;i++) { flag[i]= 0; } pthread_t t[2]; for(i=0;i<2;i++) { pthread_create(&t[i],NULL,peterson,(void *) (intptr_t) i); } for(i=0;i<2;i++) { pthread_join(t[i],NULL); } printf("shared Counter:%d\n",sharedCounter); exit(0); } 

将变量声明为“volatile”将仅阻止对这些变量的读取或写入进行重新排序。