我想检查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("%dt",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:%dn",sharedCounter); exit(0); }
将变量声明为“volatile”将仅阻止对这些变量的读取或写入进行重新排序。
需要了解更多c/c++开发分享Peterson的算法对各种优化标志的行为,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享Peterson的算法对各种优化标志的行为相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979177.html