gpt4 book ai didi

multithreading - 将推力与openmp一起使用: no substantial speed up obtained

转载 作者:行者123 更新时间:2023-12-03 13:00:13 33 4
gpt4 key购买 nike

我有兴趣将大部分使用Thrust GPU库编写的代码移植到多核CPU。值得庆幸的是,the website说推力代码可以与诸如OpenMP/Intel TBB之类的线程环境一起使用。

我在下面编写了一个简单的代码,用于对大型数组进行排序,以使用支持多达16个Open MP线程的计算机查看加速。

在此机器上获得的用于排序大小为1600万的随机数组的时间为

STL:1.47秒
推力(16线程):1.21 s

似乎几乎没有任何提速。我想知道如何像使用GPU一样大幅提高使用OpenMP对数组进行排序的速度。

代码在下面(文件sort.cu)。编译执行如下:

nvcc -O2 -o sort sort.cu -Xcompiler -fopenmp -DTHRUST_DEVICE_SYSTEM = THRUST_DEVICE_BACKEND_OMP -lgomp

NVCC版本为5.5
正在使用的Thrust库版本是v1.7.0

#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <stdio.h>
#include <algorithm>
#include <ctime>
#include <time.h>
#include "thrust/sort.h"

int main(int argc, char *argv[])
{
int N = 16000000;
double* myarr = new double[N];

for (int i = 0; i < N; ++i)
{
myarr[i] = (1.0*rand())/RAND_MAX;
}
std::cout << "-------------\n";

clock_t start,stop;
start=clock();
std::sort(myarr,myarr+N);
stop=clock();

std::cout << "Time taken for sorting the array with STL is " << (stop-start)/(double)CLOCKS_PER_SEC;

//--------------------------------------------

srand(1);
for (int i = 0; i < N; ++i)
{
myarr[i] = (1.0*rand())/RAND_MAX;
//std::cout << myarr[i] << std::endl;
}

start=clock();
thrust::sort(myarr,myarr+N);
stop=clock();

std::cout << "------------------\n";


std::cout << "Time taken for sorting the array with Thrust is " << (stop-start)/(double)CLOCKS_PER_SEC;
return 0;
}

最佳答案

device backend refers to the behavior of operations performed on a thrust::device_vector或类似的引用。 Thrust将您要传递的数组/指针解释为主机指针,并对其执行基于主机的操作,这些操作不受设备后端设置的影响。

有多种方法可以解决此问题。如果您阅读了设备后端文档,则将找到常规示例和特定于omp的示例。我认为,您甚至可以指定其他host backend,该代码应具有所需的行为(OMP使用)。

解决此问题后,您可能会得到其他结果惊喜:推力似乎可以快速对数组进行排序,但是执行时间非常长。我相信这是由于the clock() function being affected by the number of OMP threads in use(无论如何在Linux上)。

下面的代码/示例运行解决了这些问题,似乎使我4个线程的速度提高了约3倍。

$ cat t592.cu
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <stdio.h>
#include <algorithm>
#include <ctime>
#include <sys/time.h>
#include <time.h>
#include <thrust/device_ptr.h>
#include <thrust/sort.h>

int main(int argc, char *argv[])
{
int N = 16000000;
double* myarr = new double[N];

for (int i = 0; i < N; ++i)
{
myarr[i] = (1.0*rand())/RAND_MAX;
}
std::cout << "-------------\n";

timeval t1, t2;
gettimeofday(&t1, NULL);
std::sort(myarr,myarr+N);
gettimeofday(&t2, NULL);
float et = (((t2.tv_sec*1000000)+t2.tv_usec)-((t1.tv_sec*1000000)+t1.tv_usec))/float(1000000);

std::cout << "Time taken for sorting the array with STL is " << et << std::endl;;

//--------------------------------------------

srand(1);
for (int i = 0; i < N; ++i)
{
myarr[i] = (1.0*rand())/RAND_MAX;
//std::cout << myarr[i] << std::endl;
}
thrust::device_ptr<double> darr = thrust::device_pointer_cast<double>(myarr);
gettimeofday(&t1, NULL);
thrust::sort(darr,darr+N);
gettimeofday(&t2, NULL);
et = (((t2.tv_sec*1000000)+t2.tv_usec)-((t1.tv_sec*1000000)+t1.tv_usec))/float(1000000);

std::cout << "------------------\n";


std::cout << "Time taken for sorting the array with Thrust is " << et << std::endl ;
return 0;
}

$ nvcc -O2 -o t592 t592.cu -Xcompiler -fopenmp -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_BACKEND_OMP -lgomp
$ OMP_NUM_THREADS=4 ./t592
-------------
Time taken for sorting the array with STL is 1.31956
------------------
Time taken for sorting the array with Thrust is 0.468176
$

你的旅费可能会改变。特别是,当您使用4个线程以上时,可能看不到任何改善。可能有许多因素会阻止OMP代码扩展到超过一定数量的线程。排序通常是一种受内存限制的算法,因此您可能会观察到增加,直到您使内存子系统达到饱和,然后再没有其他核心增加了。根据您的系统,您可能已经处在这种情况下,在这种情况下,您可能看不到OMP样式多线程的任何改进。

关于multithreading - 将推力与openmp一起使用: no substantial speed up obtained,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26432462/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com