我正在寻找排序一个大型三维数组沿着z轴。
示例数组为X x Y x Z(1000x1000x5)
我想沿着z轴排序,所以我会沿着z轴对5个元素执行1000x1000次排序。
编辑更新:尝试使用下面的thrust。它是可用的,我会把输出存储回去,但是这非常慢,因为我在每个(x,y)位置一次排序5个元素:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <thrust/device_ptr.h>
#include <thrust/sort.h>
#include <thrust/gather.h>
#include <thrust/iterator/counting_iterator.h>
int main(){
int x = 1000, y = 1000, z = 5;
float*** unsorted_cube = new float** [x];
for (int i = 0; i < x; i++)
{
// Allocate memory blocks for
// rows of each 2D array
unsorted_cube[i] = new float* [y];
for (int j = 0; j < y; j++)
{
// Allocate memory blocks for
// columns of each 2D array
unsorted_cube[i][j] = new float[z];
}
}
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
unsorted_cube[i][j][0] = 4.0f;
unsorted_cube[i][j][1] = 3.0f;
unsorted_cube[i][j][2] = 1.0f;
unsorted_cube[i][j][3] = 5.0f;
unsorted_cube[i][j][4] = 2.0f;
}
}
for (int i = 0; i < 5; i++)
{
printf("unsorted_cube first 5 elements to sort at (0,0): %f\n", unsorted_cube[0][0][i]);
}
float* temp_input;
float* temp_output;
float* raw_ptr;
float raw_ptr_out[5];
cudaMalloc((void**)&raw_ptr, N_Size * sizeof(float));
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
temp_input[0] = unsorted_cube[i][j][0];
temp_input[1] = unsorted_cube[i][j][1];
temp_input[2] = unsorted_cube[i][j][2];
temp_input[3] = unsorted_cube[i][j][3];
temp_input[4] = unsorted_cube[i][j][4];
cudaMemcpy(raw_ptr, temp_input, 5 * sizeof(float), cudaMemcpyHostToDevice);
thrust::device_ptr<float> dev_ptr = thrust::device_pointer_cast(raw_ptr);
thrust::sort(dev_ptr, dev_ptr + 5);
thrust::host_vector<float> host_vec(5);
thrust::copy(dev_ptr, dev_ptr + 5, raw_ptr_out);
if (i == 0 && j == 0)
{
for (int i = 0; i < 5; i++)
{
temp_output[i] = raw_ptr_out[i];
}
printf("sorted_cube[0,0,0] : %f\n", temp_output[0]);
printf("sorted_cube[0,0,1] : %f\n", temp_output[1]);
printf("sorted_cube[0,0,2] : %f\n", temp_output[2]);
printf("sorted_cube[0,0,3] : %f\n", temp_output[3]);
printf("sorted_cube[0,0,4] : %f\n", temp_output[4]);
}
}
}
}
1条答案
按热度按时间cbeh67ev1#
假设数据的格式为每个xy平面中的值在存储器中连续:
data[((z * y_length) + y) * x_length + x]
(也最适合合并GPU上的内存访问)这个解决方案在硬编码
z_length
方面确实非常丑陋。人们可以使用一些C++模板-“魔法”将z_length
变成一个模板参数,但对于这个关于Thrust的答案来说,这似乎是矫枉过正。有关数组和元组之间接口的示例,请参见Convert std::tuple to std::array C++11和How to convert std::array to std::tuple?。
这个解决方案的好处是排序算法本身应该是性能最优的,我不知道
thrust::sort
是否针对这么小的输入数组进行了优化,但是你可以用我在评论中提出的任何自己编写的排序算法来代替它。如果你希望能够使用不同的
z_length
而不遇到这些麻烦,你可能更喜欢这个解决方案,它在全局内存中排序,这远非最优,而且感觉有点笨拙,因为它使用Thrust几乎只是为了启动内核。data[((x * y_length) + y) * z_length + z]
如果您同意将
z_length
作为模板参数,那么这可能是一个结合了两个领域优点的解决方案(数据格式与第一个示例类似):