高效Tensor張量生成

高效Tensor張量生成

Efficient Tensor Creation

從C++中的Excel數據中創建Tensor張量的方法有很多種,在簡單性和性能之間都有不同的折衷。本文討論了一些方法及其權衡。

提示

繼續閱讀之前請務必閱讀C++指南

將數據直接寫入Tensor張量

如果能做到這一點就更好了。

不要複製數據或包裝現有數據,而是直接將數據寫入Tensor張量。

正向

對於進程內和進程外的執行,這將在沒有副本的情況下工作

沒有內存對齊要求

不需要使用刪除程序

反向

可能需要對現有的應用程序進行大量的重構,才能使其正常工作

實例

可以將數據直接接收到Tensor張量的底層緩衝區中:

// Allocate a
tensor

auto tensor = allocator->allocate_tensor({6, 6});

// Get a pointer
to the underlying buffer

auto data = tensor->get_raw_data_ptr();

// Some function
that writes data directly into this buffer

recv_message_into_buffer(data);

或者可以手動填寫Tensor張量:

// Allocate a
tensor

auto tensor = allocator->allocate_tensor({256, 256});

const auto &dims = tensor->get_dims();

// Get an
accessor

auto accessor = tensor->accessor<2>();

// Write data
directly into it

for (int i = 0; i < dims[0]; i++)

{

for (int j = 0; j < dims[1]; j++)

{

    accessor[i][j] = i * j;

}

}

甚至可以將其與TBB並行:

// Allocate a
tensor

auto tensor = allocator->allocate_tensor({256, 256});

const auto &dims = tensor->get_dims();

// Get an
accessor

auto accessor = tensor->accessor<2>();

// Write data
into the tensor in parallel

tbb::parallel_for(

// Parallelize in blocks of 16 by 16

tbb:blocked_range2d<size_t>(0, dims[0], 16, 0, dims[1], 16),



// Run this lambda in parallel for each block in the range above

[&](const blocked_range2d<size_t>& r) {

    for(size_t i = r.rows().begin(); i != r.rows().end(); i++)

    {

        for(size_t j = r.cols().begin(); j != r.cols().end(); j++)

        {

            accessor[i][j] = i * j;

        }

    }

}

);

包裝現有內存

如果已經在某個緩衝區中保存了數據,那麼這個方法很好。

正向

在進程內執行期間,這將在沒有副本的情況下工作

如果已經有數據很容易做到

反向

需要了解什麼是刪除者以及如何正確使用

爲了有效地使用TF,數據需要64字節對齊

注意:這不是一個硬性要求,但是TF可以在引擎蓋下複製未對齊的數據

與#1相比,這會在進程外執行期間生成一個額外的副本

實例

從cv::Mat包裝數據:

cv::Mat image = … // An image from somewhere

auto tensor = allocator->tensor_from_memory<uint8_t>(

// Dimensions

{1, image.rows, image.cols, image.channels()},



// Data

image.data,



// Deleter

[image](void * unused) {

    // By capturing `image` in this deleter, we ensure

    // that the underlying data does not get deallocated

    // before we're done with the tensor.

}

);

將數據複製到Tensor張量中

正向

很容易做到

無內存對齊要求

不需要使用刪除程序

反向

在進程內執行期間總是生成一個額外的副本

與#1相比,這會在進程外執行期間生成一個額外的副本(儘管此副本是由用戶顯式編寫的)
實例

從cv::Mat複製:

cv::Mat image = … // An image from somewhere

auto tensor = allocator->allocate_tensor<uint8_t>(

// Dimensions

{1, image.rows, image.cols, image.channels()}

);

// Copy data
into the tensor

tensor->copy_from(image.data, tensor->get_num_elements());

該用哪一個?

一般來說,按業績衡量的方法順序如下:

直接將數據寫入Tensor張量

包裝現有內存

將數據複製到Tensor張量中

也就是說,分析是朋友。

簡單性和性能之間的折衷對於大Tensor張量和小Tensor張量也是不同的,因爲副本對於小Tensor張量更便宜。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章