C++ CUDA排序Z轴3D阵列C++/刺

C++ CUDA排序Z轴3D阵列C++/刺,c++,sorting,cuda,thrust,C++,Sorting,Cuda,Thrust,我希望沿着z轴对大型3D阵列进行排序 示例阵列为X X Y X Z(1000x1000x5) 我想沿z轴排序,因此我将沿z轴对5个元素执行1000x1000排序 编辑更新:尝试使用下面的推力。它是功能性的,我会将输出存储回去,但这非常慢,因为我一次对每个(x,y)位置的5个元素进行排序: #include <stdio.h> #include <stdlib.h> #include <iostream> #include <thrust/device_

我希望沿着z轴对大型3D阵列进行排序

示例阵列为X X Y X Z(1000x1000x5)

我想沿z轴排序,因此我将沿z轴对5个元素执行1000x1000排序

编辑更新:尝试使用下面的推力。它是功能性的,我会将输出存储回去,但这非常慢,因为我一次对每个(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]);
        }
    }
}
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(){
int x=1000,y=1000,z=5;
浮点***未排序的_立方体=新浮点**[x];
对于(int i=0;i
假设数据的格式是每个xy平面中的值在内存中是连续的:
数据[((z*y_长度)+y)*x_长度+x]
(这也是在GPU上合并内存访问的最佳方式)

#包括
#包括
#包括
#包括
void sort_in_z_dir(推力::设备向量和数据,
int x_length,int y_length){//z_length==5
自动z_步幅=x_长度*y_长度;
推力:每个(
推力::make_-zip_迭代器(推力::make_元组(
data.begin(),
data.begin()+z_跨步,
data.begin()+2*z_步长,
data.begin()+3*z_步,
data.begin()+4*z_)),
推力::make_-zip_迭代器(推力::make_元组(
data.begin()+z_跨步,
data.begin()+2*z_步长,
data.begin()+3*z_步,
data.begin()+4*z_步长,
data.begin()+5*z_)),
[](推力::元组和值){
浮点本地_数据[5]={推力::获取(值),
推力::获取(值),
推力::获取(值),
推力::获取(值),
推力::获取(值)};
推力::排序(推力::顺序,本地_数据,本地_数据+5);
推力::获取(值)=本地_数据[0];
推力::获取(值)=本地_数据[1];
推力::获取(值)=本地_数据[2];
推力::获取(值)=本地_数据[3];
推力::获取(值)=本地_数据[4];
});
}
就硬编码
z_长度
而言,此解决方案无疑非常难看。你可以使用一些C++模板——“魔术”来将<代码> ZyStime>代码变成模板参数,但是对于这个关于推力的答案,这似乎是多余的。 有关数组和元组之间接口的示例,请参见和

这个解决方案的好处是,根据排序算法本身,它应该是非常优化的性能。我不知道
asch::sort
是否针对如此小的输入数组进行了优化,但您可以用我在评论中提出的任何自行编写的排序算法来代替它

如果您希望能够使用不同的
z_长度
,而无需所有这些麻烦,您可能会更喜欢这种解决方案,它在全局内存中排序,这远远不是最优的,而且感觉有点粗糙,因为它几乎只在启动内核时使用推力。在这里,您希望以另一种方式对数据进行排序:
data[((x*y_长度)+y)*z_长度+z]

#包括
#包括
#包括
#包括
void sort_in_z_dir_可选(推力::设备向量和数据,
整数x_长度、整数y_长度、整数z_长度){
int n_螺纹=x_长度*y_长度;
推力:每个(
推力::使_计数_迭代器(0),
推力::生成计数迭代器(n个线程),
[ddata=推力::原始指针转换(data.data()),z长度(intIDX){
推力::排序(推力::顺序,
ddata+z_长度*idx,
ddata+z_长度*(idx+1));
});
}
如果您同意将
z_length
作为一个模板参数,那么这可能是一个结合了两方面优点的解决方案(如第一个示例中的数据格式):

#包括
#包括
#包括
#包括
模板
无效排序位于中间地面(推力::设备向量和数据,
整数x_长度