Bagikan melalui


Pengikatan di DirectML

Di DirectML, pengikatan mengacu pada lampiran sumber daya ke alur untuk digunakan GPU selama inisialisasi dan eksekusi operator pembelajaran mesin Anda. Sumber daya ini dapat berupa tensor input dan output, misalnya, serta sumber daya sementara atau persisten yang dibutuhkan operator.

Topik ini membahas detail konseptual dan prosedural pengikatan. Kami menyarankan agar Anda juga sepenuhnya membaca dokumentasi untuk API yang Anda panggil, termasuk parameter dan Komentar.

Ide penting dalam mengikat

Daftar langkah-langkah di bawah ini berisi deskripsi tingkat tinggi tentang tugas terkait pengikatan. Anda perlu mengikuti langkah-langkah ini setiap kali Anda menjalankan yang dapat dikirim—yang dapat dikirim adalah penginisialisasi operator atau operator yang dikompilasi. Langkah-langkah ini memperkenalkan ide, struktur, dan metode penting yang terlibat dalam pengikatan DirectML.

Bagian berikutnya dalam topik ini menggali lebih dalam dan menjelaskan tugas pengikatan ini secara lebih rinci, dengan cuplikan kode ilustrasi yang diambil dari contoh kode aplikasi DirectML minimal .

  • Panggil IDMLDispatchable::GetBindingProperties pada dispatchable untuk menentukan berapa banyak deskriptor yang dibutuhkan, serta kebutuhan sumber daya sementara/perseninya.
  • Buat tumpukan deskriptor Direct3D 12 yang memiliki ukuran yang cukup untuk deskriptor tersebut, dan kaitkan ke alur proses.
  • Panggil IDMLDevice::CreateBindingTable untuk membuat tabel pengikatan DirectML untuk mewakili sumber daya yang terikat ke alur. Gunakan struktur DML_BINDING_TABLE_DESC untuk menjelaskan tabel pengikatan Anda, termasuk subset deskriptor yang ditunjukkannya dalam tumpukan deskriptor.
  • Buat sumber daya sementara/persisten sebagai sumber daya buffer Direct3D 12, jelaskan dengan struktur DML_BUFFER_BINDING dan DML_BINDING_DESC , dan tambahkan ke tabel pengikatan.
  • Jika yang dapat dikirim adalah operator yang dikompilasi, buat buffer elemen tensor sebagai sumber daya buffer Direct3D 12. Isi/unggah konten tersebut, jelaskan menggunakan struktur DML_BUFFER_BINDING dan DML_BINDING_DESC, dan tambahkan ke dalam tabel pengikatan.
  • Teruskan tabel pengikatan Anda sebagai parameter saat Anda memanggil IDMLCommandRecorder::RecordDispatch.

Mengambil properti pengikatan dari dispatchable

Struktur DML_BINDING_PROPERTIES menjelaskan kebutuhan pengikatan operator yang dapat dieksekusi (penginisialisasi operator atau operator yang dikompilasi). Properti terkait pengikatan ini mencakup jumlah deskriptor yang harus Anda ikat ke yang dapat dikirim, serta ukuran dalam byte sumber daya sementara dan/atau persisten yang dibutuhkannya.

Nota

Bahkan untuk beberapa operator dengan jenis yang sama, jangan membuat asumsi tentang mereka memiliki persyaratan pengikatan yang sama. Kueri properti pengikatan untuk setiap penginisialisasi dan operator yang Anda buat.

Panggil IDMLDispatchable::GetBindingProperties untuk mengambil DML_BINDING_PROPERTIES.

winrt::com_ptr<::IDMLCompiledOperator> dmlCompiledOperator;
// Code to create and compile a DirectML operator goes here.

DML_BINDING_PROPERTIES executeDmlBindingProperties{
    dmlCompiledOperator->GetBindingProperties()
};

winrt::com_ptr<::IDMLOperatorInitializer> dmlOperatorInitializer;
// Code to create a DirectML operator initializer goes here.

DML_BINDING_PROPERTIES initializeDmlBindingProperties{
    dmlOperatorInitializer->GetBindingProperties()
};

UINT descriptorCount = ...

Nilai descriptorCount yang Anda ambil di sini menentukan ukuran (minimum) dari tumpukan deskriptor dan tabel pengikatan yang Anda buat di dua langkah berikutnya.

DML_BINDING_PROPERTIES juga berisi TemporaryResourceSize anggota, yang merupakan ukuran minimum dalam byte sumber daya sementara yang harus terikat ke tabel pengikatan untuk objek yang dapat dikirim ini. Nilai nol berarti bahwa sumber daya sementara tidak diperlukan.

Anggota PersistentResourceSize, yang merupakan ukuran minimum dalam byte dari sumber daya persisten yang harus terikat ke tabel pengikatan untuk objek siap kirim ini. Nilai nol berarti bahwa sumber daya persisten tidak diperlukan. Sumber daya persisten, jika diperlukan, harus disediakan selama inisialisasi operator yang dikompilasi (di mana terikat sebagai output penginisialisasi operator) serta selama eksekusi. Ada lebih banyak tentang ini nanti dalam topik ini. Hanya operator yang dikompilasi yang memiliki sumber daya persisten—penginisialisasi operator selalu mengembalikan nilai 0 untuk anggota ini.

Jika Anda memanggil IDMLDispatchable::GetBindingProperties pada penginisialisasi operator baik sebelum dan sesudah panggilan ke IDMLOperatorInitializer::Reset, maka dua set properti pengikatan yang diambil tidak dijamin identik.

Menjelaskan, membuat, dan mengikat tumpukan deskriptor

Dalam hal deskriptor, tanggung jawab Anda dimulai dan diakhiri dengan himpunan deskriptor itu sendiri. DirectML sendiri mengurus pembuatan dan pengelolaan deskriptor di dalam heap yang Anda sediakan.

Jadi, gunakan struktur D3D12_DESCRIPTOR_HEAP_DESC untuk menggambarkan heap yang ukurannya cukup untuk jumlah deskriptor yang dibutuhkan oleh dispatchable. Kemudian buat dengan ID3D12Device::CreateDescriptorHeap. Dan, terakhir, panggil ID3D12GraphicsCommandList::SetDescriptorHeaps untuk mengikat tumpukan deskriptor Anda ke alur.

winrt::com_ptr<::ID3D12DescriptorHeap> d3D12DescriptorHeap;

D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDescription{};
descriptorHeapDescription.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
descriptorHeapDescription.NumDescriptors = descriptorCount;
descriptorHeapDescription.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;

winrt::check_hresult(
    d3D12Device->CreateDescriptorHeap(
        &descriptorHeapDescription,
        _uuidof(d3D12DescriptorHeap),
        d3D12DescriptorHeap.put_void()
    )
);

std::array<ID3D12DescriptorHeap*, 1> d3D12DescriptorHeaps{ d3D12DescriptorHeap.get() };
d3D12GraphicsCommandList->SetDescriptorHeaps(
    static_cast<UINT>(d3D12DescriptorHeaps.size()),
    d3D12DescriptorHeaps.data()
);

Menjelaskan dan membuat tabel pengikatan

Tabel pengikatan DirectML mewakili sumber daya yang Anda ikat ke alur agar dapat dikirim untuk digunakan. Sumber daya tersebut dapat berupa tensor input dan output (atau parameter lain) untuk operator, atau dapat berupa berbagai sumber daya sementara dan persisten yang digunakan dalam pengiriman.

Gunakan struktur DML_BINDING_TABLE_DESC untuk menjelaskan tabel pengikatan Anda, termasuk objek yang dapat didistribusikan yang tabel pengikatannya akan mewakili pengikatan, dan rentang deskriptor (dari tumpukan deskriptor yang baru saja Anda buat) yang ingin Anda rujuk dalam tabel pengikatan tersebut (di mana DirectML dapat menulis deskriptor). Nilai descriptorCount (salah satu properti pengikatan yang kami ambil pada langkah pertama) memberi tahu kami ukuran minimumnya, dalam deskriptor, dari tabel pengikatan yang diperlukan untuk objek yang dapat dikirim. Di sini, kami menggunakan nilai tersebut untuk menunjukkan jumlah maksimum deskriptor yang boleh dituliskan oleh DirectML ke dalam tumpukan kami, mulai dari awal kedua handel deskriptor CPU dan GPU yang telah disediakan.

Kemudian panggil IDMLDevice::CreateBindingTable untuk membuat tabel pengikatan DirectML. Pada langkah-langkah selanjutnya, setelah kita menciptakan sumber daya lebih lanjut untuk komponen yang dapat diatur, kita akan menambahkan sumber daya tersebut ke dalam tabel pengikatan.

Alih-alih meneruskan DML_BINDING_TABLE_DESC ke panggilan ini, Anda dapat meneruskan nullptr, menunjukkan tabel pengikatan kosong.

DML_BINDING_TABLE_DESC dmlBindingTableDesc{};
dmlBindingTableDesc.Dispatchable = dmlOperatorInitializer.get();
dmlBindingTableDesc.CPUDescriptorHandle = d3D12DescriptorHeap->GetCPUDescriptorHandleForHeapStart();
dmlBindingTableDesc.GPUDescriptorHandle = d3D12DescriptorHeap->GetGPUDescriptorHandleForHeapStart();
dmlBindingTableDesc.SizeInDescriptors = descriptorCount;

winrt::com_ptr<::IDMLBindingTable> dmlBindingTable;
winrt::check_hresult(
    dmlDevice->CreateBindingTable(
        &dmlBindingTableDesc,
        __uuidof(dmlBindingTable),
        dmlBindingTable.put_void()
    )
);

Urutan di mana DirectML menulis deskriptor ke dalam tumpukan tidak ditentukan, sehingga aplikasi Anda harus berhati-hati untuk tidak menimpa deskriptor yang dibungkus oleh tabel pengikatan. Handle deskriptor CPU dan GPU yang disediakan mungkin berasal dari heap yang berbeda, namun kemudian menjadi tanggung jawab aplikasi Anda untuk memastikan bahwa seluruh rentang deskriptor yang dirujuk oleh handle deskriptor CPU disalin ke dalam rentang yang dirujuk oleh handle deskriptor GPU sebelum pelaksanaan menggunakan tabel pengikatan ini. Tumpukan deskriptor tempat pegangan disediakan harus memiliki jenis D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV. Selain itu, tumpukan yang dirujuk oleh GPUDescriptorHandle harus berupa tumpukan deskriptor yang terlihat oleh shader.

Anda dapat me-reset tabel pengikatan untuk menghapus sumber daya apa pun yang telah Anda tambahkan ke dalamnya, sekaligus mengubah properti apa pun yang Anda tetapkan pada DML_BINDING_TABLE_DESC awalnya (untuk menetapkan rentang deskriptor baru, atau menggunakannya kembali untuk penugasan yang berbeda). Cukup buat perubahan pada struktur deskripsi, dan panggil IDMLBindingTable::Reset.

dmlBindingTableDesc.Dispatchable = pIDMLCompiledOperator.get();

winrt::check_hresult(
    pIDMLBindingTable->Reset(
        &dmlBindingTableDesc
    )
);

Menjelaskan dan mengikat sumber daya sementara/persisten apa pun

Struktur DML_BINDING_PROPERTIES yang kami isi ketika kami mengambil properti pengikatan dari elemen yang dapat dijalankan berisi ukuran dalam byte dari sumber daya sementara dan/atau persisten yang dibutuhkan elemen tersebut. Jika salah satu ukuran ini bukan nol, buat sumber daya buffer Direct3D 12 dan tambahkan ke tabel pengikatan.

Dalam contoh kode di bawah ini, kami membuat sumber daya sementara berukuran temporaryResourceSize byte untuk elemen yang dapat dikirim. Kami menjelaskan bagaimana kami ingin mengikat sumber daya, lalu menambahkan pengikatan tersebut ke tabel pengikatan.

Karena kami mengikat satu sumber daya buffer, kami menjelaskan pengikatan kami dengan struktur DML_BUFFER_BINDING . Dalam struktur itu, kami menentukan sumber daya buffer Direct3D 12 (sumber daya harus memiliki dimensi D3D12_RESOURCE_DIMENSION_BUFFER), serta offset dan ukuran dari buffer. Dimungkinkan juga untuk menggambarkan pengikatan untuk array buffer (bukan untuk satu buffer), dan struktur DML_BUFFER_ARRAY_BINDING ada untuk tujuan tersebut.

Untuk mengabstraksi perbedaan antara pengikatan buffer dan pengikatan array buffer, kita menggunakan struktur DML_BINDING_DESC . Anda dapat mengatur Type anggota DML_BINDING_DESC ke DML_BINDING_TYPE_BUFFER atau DML_BINDING_TYPE_BUFFER_ARRAY. Dan Anda kemudian dapat mengatur Desc anggota untuk menunjuk ke DML_BUFFER_BINDING atau ke DML_BUFFER_ARRAY_BINDING, tergantung pada Type.

Kami berurusan dengan sumber daya sementara dalam contoh ini, jadi kami menambahkannya ke tabel pengikatan dengan panggilan ke IDMLBindingTable::BindTemporaryResource.

D3D12_HEAP_PROPERTIES defaultHeapProperties{ CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT) };
winrt::com_ptr<::ID3D12Resource> temporaryBuffer;

D3D12_RESOURCE_DESC temporaryBufferDesc{ CD3DX12_RESOURCE_DESC::Buffer(temporaryResourceSize) };
winrt::check_hresult(
    d3D12Device->CreateCommittedResource(
        &defaultHeapProperties,
        D3D12_HEAP_FLAG_NONE,
        &temporaryBufferDesc,
        D3D12_RESOURCE_STATE_COMMON,
        nullptr,
        __uuidof(temporaryBuffer),
        temporaryBuffer.put_void()
    )
);

DML_BUFFER_BINDING bufferBinding{ temporaryBuffer.get(), 0, temporaryResourceSize };
DML_BINDING_DESC bindingDesc{ DML_BINDING_TYPE_BUFFER, &bufferBinding };
dmlBindingTable->BindTemporaryResource(&bindingDesc);

Sumber daya sementara (jika diperlukan) adalah memori sementara yang digunakan secara internal selama eksekusi operator, jadi Anda tidak perlu khawatir dengan isinya. Anda juga tidak perlu menyimpannya setelah panggilan Anda ke IDMLCommandRecorder::RecordDispatch telah selesai pada GPU. Ini berarti bahwa aplikasi Anda dapat merilis atau menimpa sumber daya sementara di antara pengiriman operator yang dikompilasi. Rentang buffer yang disediakan untuk diikat sebagai sumber daya sementara harus memiliki offset awal yang selaras dengan DML_TEMPORARY_BUFFER_ALIGNMENT. Jenis heap yang mendasari buffer harus D3D12_HEAP_TYPE_DEFAULT.

Namun, jika komponen yang dapat dialokasikan melaporkan ukuran lebih dari nol untuk sumber daya persisten jangka panjang, maka prosedurnya sedikit berbeda. Anda harus membuat buffer dan menjelaskan pengikatan mengikuti pola yang sama seperti yang ditunjukkan di atas. Tetapi tambahkan ke tabel pengikatan penginisialisasi operator Anda dengan panggilan ke IDMLBindingTable::BindOutputs, karena itu adalah tugas penginisialisasi operator untuk menginisialisasi sumber daya persisten. Kemudian tambahkan ke tabel pengikatan operator yang dikompilasi dengan panggilan ke IDMLBindingTable::BindPersistentResource. Lihat contoh kode aplikasi DirectML minimal untuk melihat alur kerja ini beraksi. Konten dan masa pakai sumber daya persisten harus bertahan selama operator yang dikompilasi ada. Artinya, jika operator memerlukan sumber daya persisten, aplikasi Anda harus menyediakannya selama inisialisasi dan kemudian juga menyediakannya ke semua eksekusi operator di masa mendatang tanpa memodifikasi kontennya. Sumber daya persisten biasanya digunakan oleh DirectML untuk menyimpan tabel pencarian atau data berumur panjang lainnya yang dihitung selama inisialisasi operator dan digunakan kembali pada eksekusi operator tersebut di masa mendatang. Rentang buffer yang disediakan untuk terikat sebagai buffer persisten harus memiliki offset awal yang selaras dengan DML_PERSISTENT_BUFFER_ALIGNMENT. Jenis heap yang mendasari buffer harus D3D12_HEAP_TYPE_DEFAULT.

Jelaskan dan hubungkan semua tensor

Jika Anda berurusan dengan operator yang dikompilasi (bukan dengan penginisialisasi operator), maka Anda perlu mengikat sumber daya input dan output (untuk tensor dan parameter lainnya) ke tabel pengikatan operator. Jumlah pengikatan harus sama persis dengan jumlah input operator, termasuk tensor opsional. Tensor input dan output tertentu dan parameter lain yang diambil operator didokumenkan dalam topik untuk operator tersebut (misalnya, DML_ELEMENT_WISE_IDENTITY_OPERATOR_DESC).

Sumber daya tensor adalah buffer yang berisi nilai elemen individual tensor. Anda mengunggah dan membaca kembali buffer tersebut ke/dari GPU menggunakan teknik Direct3D 12 reguler (Mengunggah sumber daya dan Membaca kembali data melalui buffer). Lihat contoh kode aplikasi DirectML minimal untuk melihat teknik ini beraksi.

Terakhir, jelaskan pengikatan sumber daya input dan output Anda dengan struktur DML_BUFFER_BINDING dan DML_BINDING_DESC , lalu tambahkan ke tabel pengikatan operator yang dikompilasi dengan panggilan ke IDMLBindingTable::BindInputs dan IDMLBindingTable::BindOutputs. Saat Anda memanggil metode IDMLBindingTable::Bind* , DirectML menulis satu atau beberapa deskriptor ke dalam rentang deskriptor CPU.

DML_BUFFER_BINDING inputBufferBinding{ inputBuffer.get(), 0, tensorBufferSize };
DML_BINDING_DESC inputBindingDesc{ DML_BINDING_TYPE_BUFFER, &inputBufferBinding };
dmlBindingTable->BindInputs(1, &inputBindingDesc);

DML_BUFFER_BINDING outputBufferBinding{ outputBuffer.get(), 0, tensorBufferSize };
DML_BINDING_DESC outputBindingDesc{ DML_BINDING_TYPE_BUFFER, &outputBufferBinding };
dmlBindingTable->BindOutputs(1, &outputBindingDesc);

Salah satu langkah dalam membuat operator DirectML (lihat IDMLDevice::CreateOperator) adalah mendeklarasikan satu atau beberapa struktur DML_BUFFER_TENSOR_DESC untuk menjelaskan buffer data tensor yang diambil dan dikembalikan operator. Selain jenis dan ukuran buffer tensor, Anda dapat secara opsional menentukan bendera DML_TENSOR_FLAG_OWNED_BY_DML.

DML_TENSOR_FLAG_OWNED_BY_DML menunjukkan bahwa data tensor harus dimiliki dan dikelola oleh DirectML. DirectML membuat salinan data tensor selama inisialisasi operator, dan menyimpannya di sumber daya persisten. Ini memungkinkan DirectML untuk melakukan pemformatan ulang data tensor ke dalam bentuk lain yang lebih efisien. Pengaturan bendera ini dapat meningkatkan performa, tetapi biasanya hanya berguna untuk tensor yang datanya tidak berubah selama masa pakai operator (misalnya, tensor berat). Dan bendera hanya dapat digunakan pada tensor input. Ketika bendera diatur pada deskripsi tensor tertentu, tensor yang sesuai harus terikat ke tabel pengikatan selama inisialisasi operator, dan bukan selama eksekusi (yang akan mengakibatkan kesalahan). Itulah kebalikan dari perilaku default (perilaku tanpa bendera DML_TENSOR_FLAG_OWNED_BY_DML), di mana tensor diharapkan terikat selama eksekusi, dan bukan selama inisialisasi. Semua sumber daya yang terikat ke DirectML harus berupa sumber daya heap DEFAULT atau CUSTOM.

Untuk informasi selengkapnya, lihat IDMLBindingTable::BindInputs dan IDMLBindingTable::BindOutputs.

Jalankan yang dapat dikirim

Teruskan tabel pengikatan Anda sebagai parameter saat Anda memanggil IDMLCommandRecorder::RecordDispatch.

Saat Anda menggunakan tabel pengikatan selama panggilan ke IDMLCommandRecorder::RecordDispatch, DirectML mengikat deskriptor GPU yang sesuai ke alur. Handel deskriptor CPU dan GPU tidak diperlukan untuk menunjuk ke entri yang sama dalam tumpukan deskriptor, namun itu adalah tanggung jawab aplikasi Anda untuk memastikan bahwa seluruh rentang deskriptor yang dirujuk oleh handel deskriptor CPU disalin ke dalam rentang yang dirujuk oleh handel deskriptor GPU sebelum eksekusi menggunakan tabel pengikatan ini.

winrt::com_ptr<::ID3D12GraphicsCommandList> d3D12GraphicsCommandList;
// Code to create a Direct3D 12 command list goes here.

winrt::com_ptr<::IDMLCommandRecorder> dmlCommandRecorder;
// Code to create a DirectML command recorder goes here.

dmlCommandRecorder->RecordDispatch(
    d3D12GraphicsCommandList.get(),
    dmlOperatorInitializer.get(),
    dmlBindingTable.get()
);

Terakhir, tutup daftar perintah Direct3D 12 Anda, dan kirimkan untuk dieksekusi seperti yang Anda lakukan pada daftar perintah lainnya.

Sebelum eksekusi RecordDispatch pada GPU, Anda harus mengalihkan semua sumber daya yang terikat ke status D3D12_RESOURCE_STATE_UNORDERED_ACCESS , atau ke status yang secara implisit dapat diprovokasi ke D3D12_RESOURCE_STATE_UNORDERED_ACCESS, seperti D3D12_RESOURCE_STATE_COMMON. Setelah panggilan ini selesai, sumber daya tetap dalam status D3D12_RESOURCE_STATE_UNORDERED_ACCESS. Satu-satunya pengecualian untuk ini adalah untuk kumpulan unggahan yang terikat saat menjalankan penginisialisasi operator, serta ketika satu atau beberapa tensor memiliki bendera yang disetel DML_TENSOR_FLAG_OWNED_BY_DML. Dalam kasus tersebut, semua heap unggahan yang digunakan untuk input harus berada dalam status D3D12_RESOURCE_STATE_GENERIC_READ dan akan tetap dalam status tersebut, sebagaimana diwajibkan untuk semua heap unggahan. Jika DML_EXECUTION_FLAG_DESCRIPTORS_VOLATILE tidak diatur saat mengkompilasi operator, maka semua pengikatan harus diatur pada tabel pengikatan sebelum RecordDispatch dipanggil, jika tidak, perilaku tidak ditentukan. Jika tidak, jika operator mendukung pengikatan terlambat, pengikatan sumber daya dapat ditangguhkan hingga daftar perintah Direct3D 12 dikirimkan ke antrean perintah untuk dieksekusi.

RecordDispatch bertindak secara logis seperti panggilan ke ID3D12GraphicsCommandList::Dispatch. Dengan demikian, hambatan tampilan akses tidak berurutan (UAV) diperlukan untuk memastikan urutan yang benar jika ada dependensi pada data antara tugas pengiriman. Metode ini tidak memasukkan hambatan UAV pada sumber daya input atau output. Aplikasi Anda harus memastikan bahwa hambatan UAV yang benar dilakukan pada input apa pun jika kontennya bergantung pada pengiriman upstream, dan pada output apa pun jika ada pengiriman hilir yang bergantung pada output tersebut.

Masa pakai dan sinkronisasi deskriptor dan tabel pengikatan

Model mental pengikatan yang baik di DirectML adalah bahwa di balik layar tabel pengikatan DirectML tersebut membuat dan mengelola deskriptor tampilan akses tak terurut (UAV) di dalam tumpukan deskriptor yang Anda sediakan. Jadi, semua aturan Direct3D 12 biasa berlaku seputar menyinkronkan akses ke tumpukan itu dan ke deskriptornya. Aplikasi Anda bertanggung jawab untuk melakukan sinkronisasi yang benar antara pekerjaan CPU dan GPU yang menggunakan tabel pengikatan.

Tabel pengikatan tidak dapat menimpa deskriptor ketika deskriptor tersebut sedang digunakan (misalnya oleh frame sebelumnya). Jadi, jika Anda ingin menggunakan kembali tumpukan deskriptor yang sudah terikat (misalnya, dengan memanggil Bind* lagi pada tabel pengikatan yang menunjuk padanya, atau dengan menimpa tumpukan deskriptor secara manual), maka Anda harus menunggu perintah yang sedang menggunakan tumpukan deskriptor untuk menyelesaikan eksekusi pada GPU. Tabel pengikatan tidak mempertahankan referensi kuat pada tumpukan deskriptor yang ditulisnya, sehingga Anda tidak boleh merilis tumpukan deskriptor yang dapat dilihat oleh shader sampai semua pekerjaan yang menggunakan tabel pengikatan tersebut telah selesai dieksekusi oleh GPU.

Di sisi lain, sementara tabel pengikatan menentukan dan mengelola tumpukan deskriptor, tabel tidak berisi memori itu sendiri. Jadi, Anda dapat merilis atau mengatur ulang tabel pengikatan kapan saja setelah Anda memanggil IDMLCommandRecorder::RecordDispatch dengannya (Anda tidak perlu menunggu panggilan tersebut selesai pada GPU, selama deskriptor yang mendasar tetap valid).

Tabel pengikatan tidak menyimpan referensi yang kuat pada sumber daya apa pun yang terikat menggunakannya—aplikasi Anda harus memastikan bahwa sumber daya tidak dihapus saat masih digunakan oleh GPU. Selain itu, tabel pengikatan tidak aman utas—aplikasi Anda tidak boleh memanggil metode pada tabel pengikatan secara bersamaan dari utas yang berbeda tanpa sinkronisasi.

Dan pertimbangkan bahwa dalam hal apa pun pengikatan ulang hanya diperlukan ketika Anda mengubah sumber daya mana yang terikat. Jika Anda tidak perlu mengubah sumber daya terikat, maka Anda dapat mengikat sekali saat startup, dan meneruskan tabel pengikatan yang sama setiap kali Anda memanggil RecordDispatch.

Untuk pekerjaan interleaving untuk pembelajaran mesin dan rendering, pastikan bahwa tabel binding setiap frame menunjuk ke rentang tumpukan deskriptor yang belum digunakan di GPU.

Secara opsional tentukan pengikatan operator yang terlambat

Jika Anda berurusan dengan operator yang dikompilasi (daripada dengan penginisialisasi operator), maka Anda memiliki opsi untuk menentukan pengikatan yang ditunda untuk operator. Tanpa pengikatan terlambat, Anda harus mengatur semua pengikatan pada tabel pengikatan sebelum merekam operator ke dalam daftar perintah. Dengan pengikatan terlambat, Anda dapat mengatur (atau mengubah) pengikatan pada operator yang telah Anda rekam ke dalam daftar perintah, sebelum dikirimkan ke antrean perintah.

Untuk menentukan pengikatan terlambat, panggil IDMLDevice::CompileOperator dengan flags argumen DML_EXECUTION_FLAG_DESCRIPTORS_VOLATILE.

Lihat juga

  • Windows AI