使用pthread实现多线程CPU+GPU计算

本次测试目的仅仅为了尝试能否使用pthread实现多线程对CPU和GPU分别进行控制:

  文件结构如下:

  main.cc:控制线程的主函数

  vector.cu:实现对核函数进行调用的任务函数

  vector.h:任务函数声明

  vector_kernel.cu:核函数

  vector_kernel.h:核函数声明

  生成文件如下:

  vector:最终生成的可执行文件

  main.o:生成的函数体obj

  vector.o:生成的任务函数obj

  vector_kernel.o:生成的核函数obj

  功能描述:

  线程1:执行GPU代码(向量加法)

  线程2:执行CPU代码(循环打印数据)

  线程3:执行CPU代码(循环打印数据)

  线程4:执行CPU代码(循环打印数据)

  文件代码:

  main.cc:

#include  < stdio.h >
#include 
< pthread.h >
#include 
< sys / time.h >
#include 
< stdlib.h >
#include 
< string .h >
#include 
" vector.h "


pthread_t thread[
4 ];


void   * thread1( void   * )
{
// do GPU task
float  time, start;
start 
=  clock();
printf(
" thread1:I'm thread1\n " );
int  i, n  =   100 ;
float   * a,  * b,  * c;
=  ( float   * )malloc(n  *   sizeof ( float ));
=  ( float   * )malloc(n  *   sizeof ( float ));
=  ( float   * )malloc(n  *   sizeof ( float ));
for (i  =   0 ; i  <  n; i ++ )
{
a[i] 
=   1.0f ;
b[i] 
=   1.0f ;
}
for (i  =   0 ; i  <   100 ; i ++ )
{
vectorAdd(a, b, c, n);
}
printf(
" thread1:c[%d] = %f\n " 0 , c[ 0 ]);
free(a);
free(b);
free(c);
time 
=  clock()  -  start;
printf(
" thread1: task was finished!\ncostTime1 : %f\n " , time  /  CLOCKS_PER_SEC);
pthread_exit(NULL);
}


void   * thread2( void   * )
{
// do CPU task
float  time, start;
start 
=  clock();
printf(
" thread2:I'm thread2\n " );
int  i, j, k  =   1
for (i  =   0 ; i  <   1000 ; i ++ )
{
for (j  =   0 ; j  <   1000 ; j ++ )
{
printf(
" thread2:k = %d\n " , k);
k
++ ;
}
}
time  
=  clock()  -  start;
printf(
" thread2: task was finished!\ncostTime2 : %f\n " , time  /  CLOCKS_PER_SEC);
pthread_exit(NULL);
}


void   * thread3( void   * )
{
// do CPU task
float  time, start;
start 
=  clock();
printf(
" thread3:I'm thread3\n " );
int  i, j, k  =   1
for (i  =   0 ; i  <   1000 ; i ++ )
{
for (j  =   0 ; j  <   1000 ; j ++ )
{
printf(
" thread3:k = %d\n " , k);
k
++ ;
}
}
time  
=  clock()  -  start;
printf(
" thread3: task was finished!\ncostTime3 : %f\n " , time  /  CLOCKS_PER_SEC);
pthread_exit(NULL);
}


void   * thread4( void   * )
{
// do CPU task
float  time, start;
start 
=  clock();
printf(
" thread4:I'm thread4\n " );
int  i, j, k  =   1
for (i  =   0 ; i  <   1000 ; i ++ )
{
for (j  =   0 ; j  <   1000 ; j ++ )
{
printf(
" thread4:k = %d\n " , k);
k
++ ;
}
}
time  
=  clock()  -  start;
printf(
" thread4: task was finished!\ncostTime4 : %f\n " , time  /  CLOCKS_PER_SEC);
pthread_exit(NULL);
}


void  thread_create()
{
int  temp;
memset(
& thread,  0 sizeof (thread));
if ((temp  =  pthread_create( & thread[ 0 ], NULL, thread1, NULL))  !=   0 )
printf(
" 线程1创建失败!\n " );
else
printf(
" 线程1被创建!\n " );
if ((temp  =  pthread_create( & thread[ 1 ], NULL, thread2, NULL))  !=   0 )
printf(
" 线程2创建失败!\n " );
else
printf(
" 线程2被创建!\n " );
if ((temp  =  pthread_create( & thread[ 2 ], NULL, thread3, NULL))  !=   0 )
printf(
" 线程3创建失败!\n " );
else
printf(
" 线程3被创建!\n " );
if ((temp  =  pthread_create( & thread[ 3 ], NULL, thread4, NULL))  !=   0 )
printf(
" 线程4创建失败!\n " );
else
printf(
" 线程4被创建!\n " );
}
void  thread_wait()
{
if (thread[ 0 !=   0 )
{
pthread_join(thread[
0 ], NULL);
printf(
" 线程1已经结束\n " );
}
if (thread[ 1 !=   0 )
{
pthread_join(thread[
1 ], NULL);
printf(
" 线程2已经结束\n " );
}
if (thread[ 2 !=   0 )
{
pthread_join(thread[
2 ], NULL);
printf(
" 线程3已经结束\n " );
}
if (thread[ 3 !=   0 )
{
pthread_join(thread[
3 ], NULL);
printf(
" 线程4已经结束\n " );
}
}


int  main()
{
float  time, start;
printf(
" 我是主函数,正在创建线程\n " );
start 
=  clock();
thread_create();
printf(
" 我是主函数,正在等待线程完成任务\n " );
thread_wait();
time 
=  clock()  -  start;
printf(
" costTime0 : %f\n " , time  /  CLOCKS_PER_SEC);
return   0 ;
}

  vector.cu:

#include  < stdio.h >
#include 
< stdlib.h >
#include 
< cuda.h >
#include 
" vector.h "
#include 
" vector_kernel.h "


void  vectorAdd( float   * a,  float   * b,  float   * c,  int  n)
{
float   * d_a,  * d_b,  * d_c;
cudaMalloc((
void   ** ) & d_a, n  *   sizeof ( float ));
cudaMemcpy(d_a, a, n 
*   sizeof ( float ), cudaMemcpyHostToDevice);
cudaMalloc((
void   ** ) & d_b, n  *   sizeof ( float ));
cudaMemcpy(d_b, b, n 
*   sizeof ( float ), cudaMemcpyHostToDevice);
cudaMalloc((
void   ** ) & d_c, n  *   sizeof ( float ));
cudaMemcpy(d_b, b, n 
*   sizeof ( float ), cudaMemcpyHostToDevice);
vectorAddKernel
<<< 1 , n >>> (d_a, d_b, d_c, n);
cudaMemcpy(c, d_c, n 
*   sizeof ( float ), cudaMemcpyDeviceToHost);
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
}

  vector.h:

#include  < stdio.h >
#include 
< stdlib.h >

void  vectorAdd( float   * a,  float   * b,  float   * c,  int  n);

  vector_kernel.cu:

#include  < stdio.h >
#include 
< stdlib.h >
#include 
< cuda.h >
#include 
" vector_kernel.h "


__global__ 
void  vectorAddKernel( float   * a,  float   * b,  float   * c,  int  n)
{
int  tid;
tid 
=  threadIdx.x;
if (tid  <  n)
c[tid] 
=  a[tid]  +  b[tid];
}

  vector_kernel.h:

#include  < stdio.h >
#include 
< cuda.h >
#include 
< stdlib.h >


__global__ 
void  vectorAddKernel( float   * a,  float   * b,  float   * c,  int  n);

  而最主要的是makefile的内容,由于nvcc会将.cu生成obj默认为c++方式,所以,需要将主函数改为.cc文件,不然将会编译出错!

  makefile:

vector : main.o vector.o vector_kernel.o
nvcc 
- o vector main.o vector.o vector_kernel.o


vector_kernel.o : vector_kernel.cu vector_kernel.h
nvcc 
- c vector_kernel.cu


vector.o : vector.cu vector.h vector_kernel.h
nvcc 
- c vector.cu


main.o : main.cc vector.h
cc 
- lpthread  - c main.cc

  通过测试时间可以知道几个线程之间的执行关系,大家自己测试啦~

  以下是一个运行结果:

        更多内容请点击:

        CUDA专区:http://cuda.it168.com/

        CUDA论坛:http://cudabbs.it168.com/


原文链接:地址

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用pthread实现多线程矩阵乘法的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define ROWS 1000 #define COLS 1000 int mat1[ROWS][COLS], mat2[ROWS][COLS], res[ROWS][COLS]; // 矩阵乘法的计算函数 void* multiply(void* args) { int row = *(int*)args; for (int j = 0; j < COLS; ++j) { res[row][j] = 0; for (int k = 0; k < ROWS; ++k) { res[row][j] += mat1[row][k] * mat2[k][j]; } } pthread_exit(NULL); } int main() { // 初始化两个矩阵 for (int i = 0; i < ROWS; ++i) { for (int j = 0; j < COLS; ++j) { mat1[i][j] = rand() % 100; mat2[i][j] = rand() % 100; } } // 创建线程 pthread_t threads[ROWS]; for (int i = 0; i < ROWS; ++i) { int* arg = malloc(sizeof(*arg)); *arg = i; pthread_create(&threads[i], NULL, multiply, arg); } // 等待线程完成 for (int i = 0; i < ROWS; ++i) { pthread_join(threads[i], NULL); } // 打印结果 for (int i = 0; i < ROWS; ++i) { for (int j = 0; j < COLS; ++j) { printf("%d ", res[i][j]); } printf("\n"); } return 0; } ``` 在这个示例代码中,我们首先定义了两个矩阵 `mat1` 和 `mat2`,以及一个结果矩阵 `res`,并对 `mat1` 和 `mat2` 进行了随机初始化。然后,我们创建了 `ROWS` 个线程,每个线程负责计算结果矩阵 `res` 的一行。在线程函数 `multiply` 中,我们使用两个循环分别计算了结果矩阵 `res` 的一行中的每个元素。最后,我们等待所有线程完成,并打印结果矩阵。 需要注意的是,在创建线程时,我们需要将每个线程要计算的行数作为参数传递给线程函数 `multiply`,因此我们需要在创建线程前动态地分配内存来存储这些参数,并在线程函数结束后释放该内存。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值