Kekurangan proses sistem keamanan data penyalinan adalah bahwa itu juga mengisolasi hasil pekerjaan dalam setiap salinan. Untuk mengatasi keterbatasan ini Anda perlu menyimpan hasilnya dalam jenis memori bersama yang disebut NativeContainer.
A NativeContainer
adalah tipe nilai yang dikelola yang menyediakan pembungkus C# yang aman untuk memori asli. Ini berisi pointer ke alokasi yang tidak dikelola. Ketika digunakan dengan Sistem Kerja Unity C#, NativeContainer
memungkinkan pekerjaan untuk mengakses data bersama dengan benang utama daripada bekerja dengan salinan.
Unity kapal dengan NativeContainer
disebut NativeArray. Anda juga dapat memanipulasi NativeArray
dengan NativeSlice untuk mendapatkan subset NativeArray
dari posisi tertentu ke panjang tertentu.
Note: Paket (ECS) memperpanjang ruang nama Unity.Collections
untuk mencakup jenis lain dari NativeContainer
:
NativeList
- a resizable NativeArray
.NativeHashMap
- pasangan kunci dan nilai.NativeMultiHashMap
- beberapa nilai per kunci.NativeQueue
- pertama di, pertama kali keluar (FIFO) queue.Sistem keamanan dibangun menjadi semua tipe NativeContainer
. Ini melacak apa yang membaca dan menulis ke setiap NativeContainer
.
Note: Semua pemeriksaan keamanan pada jenis NativeContainer
(seperti keluar dari pemeriksaan batas, cek penguraian, dan pemeriksaan kondisi balap) hanya tersedia di Unity Editor dan Play mode.
Bagian dari sistem keamanan ini adalah DisposeSentinel dan AtomicSafetyHandle. DisposeSentinel
mendeteksi kebocoran memori dan memberi Anda kesalahan jika Anda belum membebaskan memori Anda dengan benar. Pemicu kesalahan kebocoran memori terjadi lama setelah kebocoran terjadi.
Gunakan AtomicSafetyHandle
untuk mentransfer kepemilikan kode NativeContainer
. Misalnya, jika dua pekerjaan yang dijadwalkan menulis ke NativeArray
yang sama, sistem keamanan membuang pengecualian dengan pesan kesalahan yang jelas yang menjelaskan mengapa dan bagaimana memecahkan masalah. Sistem keamanan melempar pengecualian ini ketika Anda menjadwalkan pekerjaan yang terpencil.
Dalam hal ini, Anda dapat menjadwalkan pekerjaan dengan ketergantungan. Pekerjaan pertama dapat menulis ke NativeContainer
, dan setelah selesai mengeksekusi, pekerjaan berikutnya kemudian dapat membaca dengan aman dan menulis ke NativeContainer
yang sama. Batasan membaca dan menulis juga berlaku ketika mengakses data dari benang utama. Sistem keamanan memungkinkan beberapa pekerjaan untuk membaca dari data yang sama sejajar.
Secara default, ketika pekerjaan memiliki akses ke NativeContainer
, memiliki akses membaca dan menulis. Konfigurasi ini dapat memperlambat kinerja. C# Job System tidak memungkinkan Anda untuk menjadwalkan pekerjaan yang telah menulis akses ke NativeContainer
pada saat yang sama dengan pekerjaan lain yang menuliskannya.
Jika pekerjaan tidak perlu menulis ke NativeContainer
, tandai atribut NativeContainer
dengan atribut [ReadOnly]
, seperti:
[ReadOnly]
public NativeArray<int> input;
Dalam contoh di atas, Anda dapat mengeksekusi pekerjaan pada saat yang sama dengan pekerjaan lain yang juga memiliki akses mudah ke NativeArray
pertama.
Note: Tidak ada perlindungan terhadap mengakses data statis dari dalam pekerjaan. Mengakses data statis menghukum semua sistem keamanan dan dapat crash Unity. Untuk informasi lebih lanjut, lihat C# Kiat Sistem Pekerjaan dan pemecahan masalah.
Saat membuat NativeContainer
, Anda harus menentukan jenis alokasi memori yang Anda butuhkan. Jenis alokasi tergantung pada panjang waktu pekerjaan berjalan. Cara ini Anda dapat menyesuaikan alokasi untuk mendapatkan kinerja terbaik mungkin dalam setiap situasi.
Ada tiga jenis Allocator untuk alokasi memori NativeContainer
dan rilis. Anda harus menentukan yang tepat ketika mengulangi NativeContainer
.
Temp
untuk lulus alokasi NativeContainer
untuk pekerjaan.Temp
tetapi lebih cepat dari Persistent
. Gunakan untuk alokasi benang-aman dalam umur empat bingkai. Login Anda harus Important: dari jenis alokasi ini dalam empat bingkai, atau konsol mencetak peringatan, yang dihasilkan dari kode asli. Sebagian besar pekerjaan kecil menggunakan jenis alokasi Dispose
ini.NativeContainer
allocation type.NativeContainer
ini. Jangan gunakan Persistent
di mana kinerja sangat penting.Contoh:
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
Note: Jumlah 1 dalam contoh di atas menunjukkan ukuran NativeArray
. Dalam hal ini, hanya memiliki satu elemen array karena hanya menyimpan satu bagian data dalam result
.