Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 优化C+中的三维成像过程+;_C++_Performance_Matrix_Multidimensional Array_3d - Fatal编程技术网

C++ 优化C+中的三维成像过程+;

C++ 优化C+中的三维成像过程+;,c++,performance,matrix,multidimensional-array,3d,C++,Performance,Matrix,Multidimensional Array,3d,我正在处理3D体积图像,可能很大(256x256x256)。我有3本这样的书,我想读入并操作。目前,每个卷都存储为一个数字文本文件,我使用ifstream读取该文件。我将其保存为矩阵(这是我通过动态分配3D数组编写的一个类)。然后我对这3个矩阵进行运算,加法,乘法,甚至傅立叶变换。到目前为止,一切都很好,但是,这需要很多时间,特别是傅里叶变换,因为它有6个嵌套循环 我想知道怎样才能加快速度。此外,我将图像存储在文本文件中是否会产生影响。我应该将它们保存为二进制还是其他更容易/更快阅读的格式?fs

我正在处理3D体积图像,可能很大(256x256x256)。我有3本这样的书,我想读入并操作。目前,每个卷都存储为一个数字文本文件,我使用
ifstream
读取该文件。我将其保存为矩阵(这是我通过动态分配3D数组编写的一个类)。然后我对这3个矩阵进行运算,加法,乘法,甚至傅立叶变换。到目前为止,一切都很好,但是,这需要很多时间,特别是傅里叶变换,因为它有6个嵌套循环

我想知道怎样才能加快速度。此外,我将图像存储在文本文件中是否会产生影响。我应该将它们保存为二进制还是其他更容易/更快阅读的格式?
fstream
是我阅读的最快方式吗?我每次使用相同的3个矩阵,但不改变它们。这有区别吗?另外,指针对指针是存储3D卷的最佳方式吗?如果没有,我还能做什么

另外,指针对指针是存储3d卷的最佳方式吗

不,那通常是非常不有效的

如果没有,我还能做什么

如果将其存储在连续块中,并在块中使用计算出的偏移量,则可能会获得更好的性能

我通常会使用这样的结构:

class DataBlock {

  unsigned int nx;
  unsigned int ny;
  unsigned int nz;
  std::vector<double> data;

  DataBlock(in_nx,in_ny,in_nz) : 
   nx(in_nx), ny(in_ny), nz(in_nz) , data(in_nx*in_ny*in_nz, 0)
  {}

  //You may want to make this check bounds in debug builds
  double& at(unsigned int x, unsigned int y, unsigned int z) { 
    return data[ x + y*nx + z*nx*ny ];
  };

  const double& at(unsigned int x, unsigned int y, unsigned int z) const { 
    return data[ x + y*nx + z*nx*ny ];
  };

  private:
    //Dont want this class copied, so remove the copy constructor and assignment.
    DataBlock(const DataBlock&);
    DataBlock&operator=(const DataBlock&);
};
类数据块{
无符号整数nx;
无符号整数;
无符号整数nz;
std::矢量数据;
数据块(在nx、ny、nz中):
nx(in_nx)、ny(in_ny)、nz(in_nz)、data(in_nx*in_ny*in_nz,0)
{}
//您可能希望在调试生成中进行此检查
double&at(无符号整数x,无符号整数y,无符号整数z){
返回数据[x+y*nx+z*nx*ny];
};
常数double&at(无符号整数x,无符号整数y,无符号整数z)常数{
返回数据[x+y*nx+z*nx*ny];
};
私人:
//不希望复制此类,因此请删除复制构造函数和赋值。
数据块(const-DataBlock&);
数据块&运算符=(常量数据块&);
};
将大型(2563个元素)3D图像文件存储为纯文本是一种资源浪费

在不丧失通用性的情况下,如果您的图像有一个纯文本文件,并且文件的每一行都包含一个值,则必须读取多个字符,直到找到行的结尾(对于3位数字,这些字符将是4个字节;对于数字,3个字节;对于换行符,1个字节)。之后,您必须将这些单个数字转换为数字。当使用二进制时,直接读取固定数量的字节,就可以得到数字您可以而且应该将其作为二进制图像写入和读取。

有几种格式可以这样做,我推荐的是VTK的元图像文件格式。在这种格式中,您有一个纯文本头文件和一个包含实际图像数据的二进制文件。通过头文件中的信息,您将知道图像有多大以及将使用的数据类型。在程序中,直接读取二进制数据并将其保存到3D数组中

如果您真的想加快速度,请使用CUDA或OpenCL,这对您的应用程序来说会非常快

< >有几个C++库,可以帮助您编写、保存和操作图像数据,包括前面提到的VTK和ITK。 2563是一个相当大的数字。解析2563个文本字符串将花费大量时间。使用二进制将使读/写过程大大加快,因为它不需要将数字转换为字符串,并且使用的空间大大减少。例如,要从文本文件中将数字123读取为
char
,程序需要将其读取为字符串,并使用大量的倍数10将其从十进制转换为二进制。然而,如果您直接将其作为二进制值写入
0b01111011
,则只需将该字节再次读回内存,而无需进行任何转换

使用十六进制数字也可以提高读取速度,因为每个十六进制数字都可以直接映射到二进制值,但如果您需要更高的速度,二进制文件是最好的选择。只需一个
fread
命令就足以在不到1秒的时间内将整个2563字节=16MB的文件加载到内存中。完成后,只需将它写回文件。为了提高速度,可以使用SIMD(SSE/AVX)、CUDA或其他并行处理技术。您可以通过多线程或仅保存非零值来进一步提高速度,因为在许多情况下,大多数值通常为0

另一个原因可能是因为你的数组很大,每个维度都是2的幂。这已在许多问题中讨论过,因此:


<>您可以考虑将最后一个维度更改为257,然后再试一次。或者更好地使用另一种算法,如more

您应该在负载和流程周围添加计时器,以便知道哪种算法占用的时间最多,并将您的优化工作集中于此。如果控制文件格式,则制作一个更易于读取的文件。如果是处理,我将重复前面的人所说的,研究有效的内存布局以及GPGPU计算。祝你好运。

3D FFT天生就很慢-你做过任何分析吗?除了你自己之外,你写过所有东西吗?或者你在使用任何库吗?无论如何一个好主意在你开始优化诸如文件读取之类的事情之前,最好测量程序其他部分所花费的时间。@Roger:是的,我知道。我还没有做任何分析。我只是粗略估计了放断点所花的时间。@ChaosCakeCoder:我自己写的。目前我不想使用任何库,只想使用基本c++注意,大小等于2次方的大型数组可能会非常慢。您应该将其改为[256][256][257],并以二进制格式逐行读/写,每行256个元素