Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.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
如何避免在arrayfire中使用翻转和转置的memcpy? 我使用ARAREFILE在GPU(OpenCL)的帮助下加速一些C++代码。我有600MB及以上的af::array,我需要沿列维度翻转,然后转置它 到目前为止,我用C++例程几乎完成了这些操作。然而,我现在想用AF来做这件事,但注意到AF库的内存使用过多。我对此有两个问题:_C++_Memory Management_Arrayfire - Fatal编程技术网

如何避免在arrayfire中使用翻转和转置的memcpy? 我使用ARAREFILE在GPU(OpenCL)的帮助下加速一些C++代码。我有600MB及以上的af::array,我需要沿列维度翻转,然后转置它 到目前为止,我用C++例程几乎完成了这些操作。然而,我现在想用AF来做这件事,但注意到AF库的内存使用过多。我对此有两个问题:

如何避免在arrayfire中使用翻转和转置的memcpy? 我使用ARAREFILE在GPU(OpenCL)的帮助下加速一些C++代码。我有600MB及以上的af::array,我需要沿列维度翻转,然后转置它 到目前为止,我用C++例程几乎完成了这些操作。然而,我现在想用AF来做这件事,但注意到AF库的内存使用过多。我对此有两个问题:,c++,memory-management,arrayfire,C++,Memory Management,Arrayfire,1) 我完全不明白为什么300MB阵列上的任何操作(如flip或T)都会占用超过900MB的内存。 2) 我想知道如何避免创建数组foo的副本。我认为,通过将操作封装在一个单独的函数中,我可以消除任何副本 我有这样的代码: void prepare_array(af::array &a) { af::array b = af::flip(a, 1); // ~1400MB a = b.T();

1) 我完全不明白为什么300MB阵列上的任何操作(如flip或T)都会占用超过900MB的内存。 2) 我想知道如何避免创建数组foo的副本。我认为,通过将操作封装在一个单独的函数中,我可以消除任何副本

我有这样的代码:

void prepare_array(af::array &a) {
  af::array b = af::flip(a, 1);              // ~1400MB
  a = b.T();                                 // ~3000MB
}

af::array foo = af::randn(768,16384,3,1,c64); // ~300MB
prepare_array(foo);
af::deviceGC();                              // ~600MB
我只需要做一次这个操作,所以速度不如内存使用重要,但我更愿意在AF框架内做这个操作

(所有内存使用统计信息都是从Debian的英伟达内核驱动程序包中读取的) CPU后端的内存使用也同样过多


感谢umar arshad的回复:当我上次在CPU上运行代码时,我分析了mem的使用情况——假设它的行为相同。我在GPU上使用gpustat和nvidia smi双重检查了测量结果。事实上,代码和测量值是不同的,正如您所解释的。现在一切都变得非常合理了——至少是GPU部分

可能在CPU上,foo一开始只是f64,因为只使用了实部,通过使用翻转或转置,它变成了c64

“分配触发特定平台上所有队列上的隐式设备同步”以及本网站的事实: 和af::printMemInfo(); 帮助我最终了解了AF的大部分内存处理。大大加快了我的程序

但是,目前,执行这两个操作(或尽可能少的开销)的唯一替代方法是使用:

// Generate/store data in std::array<af::cdouble> foo_unwrap = new af::cdouble[768*16384*3*1];

// Flip/Transpose foo_unwrap in plain C/C++, like in:
// for(column = 0; column < max_num_column/2; column++)
//   swap column with max_num_column-1-column
//
// http://www.geeksforgeeks.org/inplace-m-x-n-size-matrix-transpose/
//   but for Column-Major Order matrices
//
// and afterwards whenever needed do ad-hoc:
af::cdouble* first_elem = (af::cdouble*) &(foo_unwrap[0]); // to ensure correct type detection via AF
af::array foo = af::array(768,16384,3,1, first_elem, afDevice);
//在std::array foo_unwrap=new af::cdouble[768*16384*3*1]中生成/存储数据;
//在普通C/C++中翻转/转置foo_展开,如:
//对于(列=0;列

然而,这相当麻烦,因为我不想为行/列主格式和索引魔法而烦恼。所以我还在这里寻找建议。

ArrayFire使用内存管理器来避免不必要的分配和释放。这是必需的,因为所有分配都会在某些平台上的所有队列上触发隐式设备同步。这可能会非常昂贵,因此ArrayFire将跟踪超出范围的
af::array
s,并在必要时重用它们。ArrayFire还在启动时分配内存

在您的例子中,在randu调用时分配约600MB(
c64
是一个复杂的双精度,因此每个元素是16字节)。另一个600MB的翻转操作分配存储在
b
中。转置将分配600MB,但将保留旧值以供重用。此时,由于这些操作,您已经分配了大约1800 MB的内存

当您从
prepared_数组返回时
函数调用b将超出范围并被标记为删除。此时,您有3个缓冲区,每个缓冲区的容量为600MB。其中两个缓冲区未使用,但ArrayFire可以在将来的操作中使用这些缓冲区。调用该函数后,两个未使用的数组都将被释放,尽管您可能会分配大小相似的数组,因此保留这些数组是很有用的

您可以使用函数跟踪ArrayFire进行的分配


Disclamer:我是ArrayFire的开发者之一。

是的,我不知道
gpustat
在做什么,但数字实际上是错的(请参阅下面Umar的答案)。您可以使用
nvidia smi
了解更多信息。您还可以使用
af::deviceMemInfo
查看arrayfire在内部执行的操作。通常,当我使用arrayfire时,我会将维度视为第一维度、第二维度,而不是列、行。只要你是一致的,尺寸的表示就不重要了。当然,这不适用于线性代数运算,但AF中的某些函数(特别是matmul)具有选项参数,这些参数执行计算时,就好像数组在不重新排序数据的情况下被转置一样。有关应用程序的其他上下文也会有所帮助。因此,这不是进行此类讨论的最佳论坛。我们在谷歌群组和gitter上相当活跃。此外,如果你的转置矩阵是正方形的,那么你可以使用