这是我们想要在gpu上并行化的c ++代码:
#include <array>
#include <vector>
#include <bitset>
#include <cstdint>
#include <iostream>
#define NW 8 // use bitvectors of d=NW*32 bits, example NW=8
using namespace std;
using std::uint32_t; // 32-bit unsigned integer used inside bitvector
using std::size_t; // unsigned integer for indices
// type for bitvector
typedef array<uint32_t, NW> bitvec_t;
typedef vector<bitvec_t> list_t;
void substract_list(const list_t& L) {
// go over all unique pairs 0 <= j < i < L.size()
for (size_t i = 1; i < L.size(); ++i) {
for (size_t j = 0; j < i; ++j) {
size_t w = 0;
for (size_t k = 0; k < NW; ++k) {
w += an_array[i][k] - an_array[j][k];
}
cout << w;
}
}
我们的目标是优化此代码并使其在gpu上运行。我们目前不知道该怎么做的是如何并行化第二个for循环,因为这个for循环的大小增加,这将导致增加的线程数量,这对于cuda编程来说不是最佳的。所以我们的问题是,是否可以并行化增加的for循环,如果有的话,你们有关于如何做的提示吗?
编辑: 添加了额外的代码。
答案 0 :(得分:1)
循环可以分解为
// the first addition part
for (size_t i = 1; i < L.size(); ++i)
{
for( size_t k = 0; k < NW; ++k )
{
w += i * an_array[i][k];
}
}
// the second subtraction part
for (size_t i = 0; i < L.size(); ++i)
{
for( size_t k = 0; k < NW; ++k )
{
w -= (size-1-i) * an_array[i][k];
}
}
增加大小的循环被消灭。这种方法可以很容易地在GPU上实现。 通常,如果你有一个类似j循环的循环,你可以将if语句乘以这些计算。在GPU上,这种方法比如果更快。这可能看起来像
for (size_t i = 1; i < L.size(); ++i)
{
for (size_t j = 0; j < L.size(); ++j)
{
size_t w = 0;
for (size_t k = 0; k < NW; ++k)
{
w += an_array[i][k] - an_array[j][k] * (threadIdx.x < i);
}
}
}