MemoryView¶ ↑
MemoryView 提供功能,讓擴充套件程式庫之間可以共用記憶體中具有固定大小元素的多維均質陣列。
免責聲明¶ ↑
-
此功能仍處於實驗階段。此處描述的規格未來可能會變更。
-
此文件正在編寫中。請參閱 ruby 的主分支以取得此文件的最新版本。
概述¶ ↑
我們有時會處理某些類型的物件,其內部表示形式為連續記憶體區域中具有相同類型固定大小元素的陣列。numo-narray 中的 Numo::NArray 和 rmagick 中的 Magick::Image 是此類物件的典型範例。MemoryView 扮演樞紐的角色,可在這些函式庫之間共用此類物件的內部資料,而無需複製。
在某些領域(例如資料分析、機器學習和影像處理)中,無複製資料共用非常重要。在這些領域中,人們需要使用多個函式庫來處理大量記憶體中資料。如果我們被迫複製以在函式庫之間交換大量資料,則大量資料處理時間必定會被複製資料所佔用。您可以透過使用 MemoryView 來避免這種浪費時間。
MemoryView 有兩類 API
-
生產者 API
類別可以註冊自己的 MemoryView 項目,這允許該類別的物件公開其 MemoryView
-
消費者 API
消費者 API 允許我們取得並管理物件的 MemoryView
MemoryView 結構¶ ↑
MemoryView 結構 rb_memory_view_t
用於匯出物件的 MemoryView。此結構包含物件的參考(MemoryView 的擁有者)、匯出記憶體開頭的指標,以及描述記憶體結構的元資料。元資料可以描述具有步幅的多維陣列。
MemoryView 結構的成員¶ ↑
MemoryView 結構包含下列成員。
-
VALUE obj
透過 MemoryView 匯出記憶體的原始物件參考。
RubyVM
管理 MemoryView 匯出物件的參考計數,以保護它們免於垃圾回收。消費者不必努力保護此物件免於GC
。 -
void *data
匯出記憶體開頭的指標。
-
ssize_t byte_size
data
指向的記憶體中的位元組數。 -
bool readonly
唯讀記憶體為
true
,可寫入記憶體為false
。 -
const char *format
描述元素格式的字串,或 NULL 表示未簽署的位元組。
-
ssize_t item_size
每個元素中的位元組數。
-
const rb_memory_view_item_component_t *item_desc.components
元素中元件的元資料陣列。
-
size_t item_desc.length
item_desc.components
中的項目數。 -
ssize_t ndim
維度數。
-
const ssize_t *shape
表示每個維度中元素數的
ndim
大小陣列。當ndim
為 1 時,這可以是NULL
。 -
const ssize_t *strides
表示跳過多少位元組才能在每個維度中移動到下一個元素的
ndim
大小陣列。當ndim
為 1 時,這可以是NULL
。 -
const ssize_t *sub_offsets
當 MemoryView 顯示巢狀陣列時,包含每個維度中偏移量的
ndim
大小陣列。當 MemoryView 顯示平面陣列時,這可以是NULL
。 -
void *private_data
MemoryView 提供者在內部使用的私人資料。當任何私人資料都不必要時,這可以是
NULL
。
MemoryView API¶ ↑
使用者¶ ↑
-
bool rb_memory_view_available_p(VALUE obj)
如果
obj
支援匯出 MemoryView,則傳回true
。否則傳回false
。如果此函式傳回
true
,並不表示函式rb_memory_view_get
會成功。 -
bool rb_memory_view_get(VALUE obj, rb_memory_view_t *view, int flags)
如果指定的
obj
支援匯出符合指定flags
的 MemoryView,此函式會以 MemoryView 的資訊填入view
,並傳回true
。在此情況下,obj
的參考計數會增加。如果
obj
和flags
的指定組合無法匯出 MemoryView,此函式會傳回false
。在此情況下,view
的內容不會受到影響。當不再需要 MemoryView 時,必須使用
rb_memory_view_release
釋放已匯出的 MemoryView。 -
bool rb_memory_view_release(rb_memory_view_t *view)
釋放指定的 MemoryView
view
,並遞減view->obj
的參考計數。當不再需要 MemoryView 時,使用者必須呼叫此函式。未呼叫此函式會導致記憶體外洩。
-
ssize_t rb_memory_view_item_size_from_format(const char *format, const char **err)
計算元素佔用的位元組數。
當計算失敗時,
format
中失敗的位置會儲存在err
中,並傳回-1
。 -
void *rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices)
計算由給定的
indices
指示的項目的位置。indices
的長度必須等於view->ndim
。此函式在需要時初始化view->item_desc
。 -
VALUE rb_memory_view_get_item(rb_memory_view_t *view, const ssize_t *indices)
傳回由給定的
indices
指示的項目的 Ruby 物件表示。indices
的長度必須等於view->ndim
。此函式使用rb_memory_view_get_item_pointer
。 -
rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const bool readonly)
將 view
的成員填入為 1 維的位元組陣列。
-
void rb_memory_view_fill_contiguous_strides(const ssize_t ndim, const ssize_t item_size, const ssize_t *const shape, const bool row_major_p, ssize_t *const strides)
使用給定的元素大小,以給定形狀的連續陣列的位元組跨距填入 strides
陣列。
-
void rb_memory_view_prepare_item_desc(rb_memory_view_t *view)
填入 view
的 item_desc
成員。
-
bool rb_memory_view_is_contiguous(const rb_memory_view_t *view)
如果 MemoryView view
中的資料是列優先或行優先連續的,則傳回 true
。
否則傳回 false
。
-
bool rb_memory_view_is_row_major_contiguous(const rb_memory_view_t *view)
如果 MemoryView view
中的資料是列優先連續的,則傳回 true
。
否則傳回 false
。
-
bool rb_memory_view_is_column_major_contiguous(const rb_memory_view_t *view)
如果 MemoryView view
中的資料是行優先連續的,則傳回 true
。
否則傳回 false
。