`
xieyj
  • 浏览: 100277 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

smp下cpu cache并行测试

阅读更多

      今天在看CPU cache时候,根据上面的例子做了个练习,发现了一个怪事情,没想明白

      例子如下,在powerpc下面跑,多个power7的CPU:

例子一test:

#include <stdio.h>

#include <sys/time.h>

#include <unistd.h>

int main()

{

        int steps = 256 * 1024 * 1024;

        int a[] = {0,0};

        int i ;

        struct timeval start ;

        struct timeval end ;

        unsigned long diff ;

        gettimeofday(&start, NULL);

        for (i=0; i<steps; i++) { a[0]++; a[0]++; }  -----此处为两个a[0]

        gettimeofday(&end, NULL);

        diff = 1000000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec);

        printf("diff----%ld\n",diff);

}

例子2 test2:

#include <stdio.h>

#include <sys/time.h>

#include <unistd.h>

int main()

{

        int steps = 256 * 1024 * 1024;

        int a[] = {0,0};

        int i ;

        struct timeval start ;

        struct timeval end ;

        unsigned long diff ;

 

        gettimeofday(&start, NULL);

        for (i=0; i<steps; i++) { a[0]++; a[1]++; }  ----此处为一个a[0],一个a[1]

        gettimeofday(&end, NULL);

        diff = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;

        printf("diff2----%ld\n",diff);

}

执行./test;./test2

结果如下:

diff----3826802

diff2----1976746

现代处理器中对不同部分指令拥有一点并发性。这使得CPU在同一时刻访问L1两处内存位置,或者执行两次简单算术操作。在第一个循环中,处理器无法发掘这种指令级别的并发性,但第二个循环中就可以。所以test2比test快近一倍。

 

但将test和test2合并在一起

#include <stdio.h>

#include <sys/time.h>

#include <unistd.h>

#define mb()   __asm__ __volatile__ ("sync" : : : "memory")  ----此是因为怀疑cpu乱序这类造成引入

int main()

{

        int steps = 256 * 1024 * 1024;

        int a[] = {0,0};

        int i ;

        struct timeval start ;

        struct timeval end ;

        unsigned long diff ;

        gettimeofday(&start, NULL);

        for (i=0; i<steps; i++) { a[0]++; a[0]++; }

        gettimeofday(&end, NULL);

        diff = 1000000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec);

        printf("diff----%ld\n",diff);

 

        mb();    ------加和不加,对输出的数字有较大影响

 

        gettimeofday(&start, NULL);

        for (i=0; i<steps; i++) { a[0]++; a[0]++; }   -----先用a[0],后面用a[1]作不同实验

        gettimeofday(&end, NULL);

        diff = 1000000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec);

        printf("diff2----%ld\n",diff);

}

加mb()

diff----3919898

diff2----6281302

去掉mb()

diff----4068821

diff2----3803478

疑问:为什么加mb()之后,执行时间要多花这么多

 

改为a[1],加mb()

diff----3815021

diff2----3473165

不加mb()

diff----3815935

diff2----3463169

考虑到误差,这两者基本一样

疑问:为什么分开两个程序,和一个程序内执行时间差别这么大。

有空看看两者产生的汇编语言,看看有什么不同之处。

并行编程真是个神奇的怪物,还有待深入。

 

       这两天稍微有点空,看了一下汇编,在上面的mb()之前产生的汇编和mb()之后产生的汇编不一样,估计就是传说中的乱序优化,在第一个gettimeofday(&start,NULL)之前加上mb(),其结果就比较正常了,a[0]++,a[0]++比a[0]++,a[1]++慢将近一倍

diff----6159865

diff2----3427905

       但不加mb(),a[1]++这个速度相比下不明显,不知何故?

       直接用 gcc -O2 -o test test.c,之后执行便变成了

diff----0

diff2----0

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics