0%

编写C并行计算程序并统计时间

注意事项

int ret = pthread_create(ids+i, NULL, calc, (void*)(seq+i));
  • 如上强制类型转换修改指针类型的时候,假如指针与其他类型的变量有加减,需要先完成加减再进行修改,否则会先将指针类型转换为void*再计算,使得指针的位置出错

  • 尽量避免使用&数组名[下标]的方式传递指针

  • 编译的时候记得再gcc最后加参数-lpthread比如

    • gcc parallelCalc.c -o par -lpthread

      c语言计时

  • 参考链接

  • 都是time.h中的

    • 一种是time_t time(time_t * timer),参数传递NULL即可
    • 另一种是直接计算硬件滴答数,要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC。
    • clock_t clock(void);

      时间统计(开1000个线程)

  • 规模为100:

    • picture 6
  • 1000:

    • picture 7
  • 10000:

    • picture 10
  • 100000:

    • picture 11
  • 1000000:

    • picture 12
  • 10000000:

    • picture 13

      CPU使用情况

  • 设置VMWare虚拟机为8核心

    • picture 14
    • 可以明显地观察到有8个核心的占用一下子升高
  • 顺序执行

    • picture 15
    • 没有明显的CPU使用(也或许是计算任务在不同的CPU之间来回变化),效率很低
    • picture 16

代码

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define SIZEOFMAT 1000
#define SIZEOFVEC 10000000
// int matrix[SIZEOFMAT][SIZEOFVEC];
// int vector[SIZEOFVEC];
int seq[SIZEOFMAT];
int* rets[SIZEOFMAT];

static void* calc(void *input)
{
// printf("enter\n");
int rowNum = *(int*)input;
int *sum = malloc(sizeof(int)); // 分配内存 不使用临时变量
*sum = 0;
// printf("线程%d: \n", rowNum);
for (int i = 0; i < SIZEOFVEC; i++)
{
*sum+=1;
}
// printf("sum: %d\n", *sum);
// printf("exit\n");
return (void*)sum;
}

int main()
{

clock_t start,end;

pthread_t ids[SIZEOFMAT];
int outVec[SIZEOFMAT];
for (int i = 0; i < SIZEOFMAT; i++)
{
seq[i] = i;
}
// for(int i = 0;i<SIZEOFMAT;i++)
// {
// for(int j = 0;j<SIZEOFVEC;j++)
// {
// matrix[i][j] = j;
// vector[j] = j;
// }
// }
start = clock();
for (int i = 0; i < SIZEOFMAT; i++)
{
int ret = pthread_create(ids+i, NULL, calc, (void*)(seq+i));
// printf("创建了%d\n", i);
if(ret)
{
printf("创建发生错误!");
exit(0);
}
}
for (int i = 0; i<SIZEOFMAT;i++)
{
// printf("joining\n");
pthread_join(ids[i], (void**)(rets+i));
}

for(int i = 0;i<SIZEOFMAT;i++)
{
// printf("%d, ", *rets[i]);
free(rets[i]);
}
end = clock();
printf("并行计算经过的时间为 %d\n", end-start);

// int stdSum = 0;
// for(int i = 0;i<SIZEOFVEC;i++)
// {
// stdSum+=i*i;
// }
// printf("\n参照: %d\n", stdSum);

start = clock();
int sumSeq[SIZEOFMAT] = {0};
for(int i = 0;i<SIZEOFMAT; i++)
{
for(int j = 0;j<SIZEOFVEC; j++)
{
sumSeq[i]+=1;
}
}
for(int i = 0;i<SIZEOFMAT;i++)
{
// printf("%d, ", sumSeq[i]);
}
end = clock();
printf("循环计算经过的时间为:%d\n", end - start);
}