Aracılığıyla paylaş


DirectML'de bağlama

DirectML'de bağlama , gpu'nun makine öğrenmesi operatörlerinizin başlatılması ve yürütülmesi sırasında kullanılması için işlem hattına kaynak ekini ifade eder. Bu kaynaklar giriş ve çıkış tensorlarının yanı sıra operatörün ihtiyaç duyduğu geçici veya kalıcı kaynaklar olabilir.

Bu konu, bağlamanın kavramsal ve yöntemsel ayrıntılarını inceler. Ayrıca, çağırdığınız API'ler için parametreler ve Açıklamalar da dahil olmak üzere belgeleri tam olarak okumanızı öneririz.

Bağlamada önemli fikirler

Aşağıdaki adım listesi, bağlamayla ilgili görevlerin üst düzey açıklamasını içerir. Her gönderilebilir öğeyi her yürüttüğünüzde şu adımları izlemeniz gerekir—gönderilebilir, bir işleç başlatıcısı veya derlenmiş bir işleçtir. Bu adımlar DirectML bağlamasında yer alan önemli fikirleri, yapıları ve yöntemleri tanıtır.

Bu konudaki sonraki bölümler daha ayrıntılıdır ve en düşük DirectML uygulama kodu örneğinden alınan açıklayıcı kod parçacıklarıyla bu bağlama görevlerini daha ayrıntılı bir şekilde açıklar.

  • IDMLDispatchable::GetBindingProperties fonksiyonunu, gönderilebilir üzerinde kaç tanımlayıcı gerektiğini ve geçici/kalıcı kaynak gereksinimlerini belirlemek için çağırın.
  • Tanımlayıcılar için yeterince büyük bir Direct3D 12 tanımlayıcı yığını oluşturun ve bunu işlem hattına bağlayın.
  • İşlem hattına bağlı kaynakları temsil eden bir DirectML bağlama tablosu oluşturmak için IDMLDevice::CreateBindingTable çağrısı yapın. Tanımlayıcı yığınında işaret ettiği tanımlayıcıların alt kümesi de dahil olmak üzere bağlama tablonuzu açıklamak için DML_BINDING_TABLE_DESC yapısını kullanın.
  • Direct3D 12 arabellek kaynakları olarak geçici/kalıcı kaynaklar oluşturun, bunları DML_BUFFER_BINDING ve DML_BINDING_DESC yapılarla açıklayın ve bağlama tablosuna ekleyin.
  • Gönderilebilir bir derlenmiş işleçse, Direct3D 12 arabellek kaynağı olarak tensor öğelerinden oluşan bir arabellek oluşturun. Bunu doldurun/karşıya yükleyin, DML_BUFFER_BINDING ve DML_BINDING_DESC yapılarla açıklayın ve bağlama tablosuna ekleyin.
  • IDMLCommandRecorder::RecordDispatch çağrısı yaptığınızda bağlama tablonuzu parametre olarak geçirin.

Dağıtılabilir bir nesnenin bağlama özelliklerini getir.

DML_BINDING_PROPERTIES yapısı, gönderilebilir (işleç başlatıcı veya derlenmiş işleç) bağlama gereksinimlerini açıklar. Bağlamayla ilgili bu özellikler, gönderilebilir değere bağlamanız gereken tanımlayıcıların sayısını ve ihtiyaç duyduğu geçici ve/veya kalıcı kaynakların bayt cinsinden boyutunu içerir.

Uyarı

Aynı türdeki birden çok işleç için bile aynı bağlama gereksinimlerine sahip olduğu varsayımlarında bulunmayın. Oluşturduğunuz her başlatıcı ve işleç için bağlama özelliklerini sorgular.

DML_BINDING_PROPERTIES almak için IDMLDispatchable::GetBindingProperties çağrısı yapın.

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 = ...

descriptorCount Burada aldığınız değer, tanımlayıcı yığınının ve sonraki iki adımda oluşturduğunuz bağlama tablosunun (en düşük) boyutunu belirler.

DML_BINDING_PROPERTIES ayrıca, bu gönderilebilir nesne için bağlama tablosuna bağlanması gereken geçici kaynağın bayt cinsinden en küçük boyutu olan bir TemporaryResourceSize üye içerir. Sıfır değeri, geçici bir kaynağın gerekli olmadığı anlamına gelir.

Bağlama tablosuna bağlanması gereken bu kalıcı kaynağın bayt cinsinden en küçük boyutunu belirten bir PersistentResourceSize üyesi, bu gönderilebilir nesne için gerekli olan minimum boyuttur. Sıfır değeri, kalıcı bir kaynağın gerekli olmadığı anlamına gelir. Gerekirse kalıcı bir kaynak, hem derlenmiş bir işlecin başlatılması sırasında (burada işleç başlatıcısının bir çıkışı olarak bağlanır) hem de yürütme sırasında sağlanmalıdır. Bu konunun ilerleyen bölümlerinde bu konu hakkında daha fazla bilgi bulabilirsiniz. Yalnızca derlenmiş işleçler kalıcı kaynaklara sahiptir; işleç başlatıcıları bu üye için her zaman 0 değerini döndürür.

IdMLOperatorInitializer::Reset çağrısından önce ve sonra bir işleç başlatıcıda IDMLDispatchable::GetBindingProperties çağrısı yaparsanız, alınan iki bağlama özelliği kümesinin aynı olacağı garanti edilmez.

Tanımlayıcı yığınını açıklama, oluşturma ve bağlama

Tanımlayıcılar açısından sorumluluğunuz, tanımlayıcı yığınının kendisiyle başlar ve biter. DirectML, sağladığınız yığının içindeki tanımlayıcıları oluşturma ve yönetmeyle ilgilenir.

Bu nedenle, dağıtılabilirin ihtiyaç duyduğu tanımlayıcıların sayısını karşılayacak kadar büyük bir yığını tanımlamak için D3D12_DESCRIPTOR_HEAP_DESC yapısını kullanın. Ardından ID3D12Device::CreateDescriptorHeap ile oluşturun. Son olarak, tanımlayıcı yığınınızı işlem hattına bağlamak için ID3D12GraphicsCommandList::SetDescriptorHeaps çağrısı yapın.

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()
);

Bağlama tablosunu açıklama ve oluşturma

DirectML bağlama tablosu, işlem hattına göndermek üzere bağladığınız kaynakları temsil eder. Bu kaynaklar bir işleç için giriş ve çıkış tensorları (veya diğer parametreler) olabileceği gibi, bir gönderilebilir öğenin birlikte çalıştığı çeşitli kalıcı ve geçici kaynaklar da olabilir.

Bağlama tablonuzu açıklamak için DML_BINDING_TABLE_DESC yapısını kullanın. Bu yapı, bağlama tablosunun bağlamalarını temsil edeceği gönderilebilir öğe ile az önce oluşturduğunuz tanımlayıcı yığınından başvurmak istediğiniz ve DirectML'nin tanımlayıcıları yazabileceği tanımlayıcı aralığını içerir. descriptorCount Değeri (ilk adımda aldığımız bağlama özelliklerinden biri), gönderilebilir nesne için gereken bağlama tablosunun tanımlayıcılarında en düşük boyutun ne olduğunu bildirir. Burada, hem sağlanan CPU hem de GPU tanıtıcı handle'larının başlangıcından itibaren DirectML'nin heap'imize yazmasına izin verilen en fazla deskriptör sayısını belirtmek için bu değeri kullanırız.

Ardından, DirectML bağlama tablosunu oluşturmak için IDMLDevice::CreateBindingTable'ı çağırın. Sonraki adımlarda, gönderilebilir için daha fazla kaynak oluşturduktan sonra bu kaynakları bağlama tablosuna ekleyeceğiz.

Çağrıya bir DML_BINDING_TABLE_DESC geçirmek yerine, nullptr kullanarak boş bir bağlama tablosu geçirebilirsiniz.

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()
    )
);

DirectML'nin tanımlayıcıları yığına yazma sırası belirtilmez, bu nedenle uygulamanızın bağlama tablosu tarafından sarmalanan tanımlayıcıların üzerine yazmamaya dikkat etmesi gerekir. Sağlanan CPU ve GPU tanıtıcıları farklı kaynak yığınlarından gelebilir, ancak bu bağlama tablosunu kullanarak yürütmeden önce, CPU tanıtıcısı ile belirtilen tanımlayıcı aralığının tamamının GPU tanıtıcısı ile belirtilen aralığa kopyalandığından emin olmak uygulamanızın sorumluluğundadır. Tanıtıcıların sağlandığı tanımlayıcı yığınının türü D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV olmalıdır. Buna ek olarak, GPUDescriptorHandle tarafından belirtilen yığın bir görsel tanımlayıcı gölgelendirici yığını olmalıdır.

Bağlama tablosunu sıfırlayarak eklediğiniz kaynakları kaldırabilirsiniz; aynı zamanda, ilk DML_BINDING_TABLE_DESC üzerinde ayarladığınız herhangi bir özelliği değiştirebilir, yeni bir tanımlayıcı aralığını kapsayacak şekilde veya farklı bir gönderim için yeniden kullanabilirsiniz. Açıklama yapısında değişiklik yapın ve IDMLBindingTable::Reset öğesini çağırın.

dmlBindingTableDesc.Dispatchable = pIDMLCompiledOperator.get();

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

Geçici/kalıcı kaynakları açıklama ve bağlama

Gönderilebilir öğemizin bağlama özelliklerini aldığımızda dolduracağımız DML_BINDING_PROPERTIES yapısı, gönderilebilir kaynakların ihtiyaç duyduğu geçici ve/veya kalıcı kaynakların bayt cinsinden boyutunu içerir. Bu boyutlardan biri sıfır değilse, bir Direct3D 12 arabellek kaynağı oluşturun ve bağlama tablosuna ekleyin.

Aşağıdaki kod örneğinde, gönderilebilir için geçici bir kaynak (temporaryResourceSize bayt boyutu) oluşturuyoruz. Kaynağı nasıl bağlamak istediğimizi açıklar ve sonra bu bağlamayı bağlama tablosuna ekleriz.

Tek bir arabellek kaynağını bağladığımız için bağlamamızı bir DML_BUFFER_BINDING yapısıyla açıklıyoruz. Bu yapıda, Direct3D 12 arabellek kaynağını (kaynağın boyutunun D3D12_RESOURCE_DIMENSION_BUFFER olması gerekir) yanı sıra arabellek içindeki başlangıç ve boyutu da belirtiriz. Bir arabellek dizisi (tek bir arabellek yerine) için bağlamayı açıklamak da mümkündür ve DML_BUFFER_ARRAY_BINDING yapısı bu amaç için mevcuttur.

Arabellek bağlaması ile arabellek dizisi bağlaması arasındaki ayrımı soyutlamak için DML_BINDING_DESC yapısını kullanırız. Type üyesini DML_BINDING_TYPE_BUFFER veya DML_BINDING_TYPE_BUFFER_ARRAY olarak ayarlayabilirsiniz. Ardından Desc bağlı olarak üyeyi bir DML_BUFFER_BINDING veya DML_BUFFER_ARRAY_BINDING işaret etmek üzere Type ayarlayabilirsiniz.

Bu örnekte geçici kaynakla ilgileniyoruz, bu nedenle idMLBindingTable::BindTemporaryResource çağrısıyla bağlama tablosuna ekliyoruz.

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);

Geçici bir kaynak (gerekirse), işlecin yürütülmesi sırasında dahili olarak kullanılan karalama belleğidir, bu nedenle içeriğiyle ilgilenmeniz gerekmez. Ayrıca, GPU'da IDMLCommandRecorder::RecordDispatch çağrınız tamamlandıktan sonra da bunu tutmanız gerekmez. Bu, uygulamanızın derlenen işlecin dağıtımları arasında geçici kaynağı serbest bırakabileceği veya üzerine yazabileceği anlamına gelir. Geçici kaynak olarak bağlanacak sağlanan arabellek aralığının başlangıç offseti DML_TEMPORARY_BUFFER_ALIGNMENT ile hizalanmış olmalıdır. Arabelleğin temelindeki yığının türü D3D12_HEAP_TYPE_DEFAULT olmalıdır.

Teyit edilebilir, daha uzun ömürlü kalıcı kaynağı için sıfır olmayan bir boyut bildirirse, işlem biraz farklıdır. Bir arabellek oluşturmanız ve yukarıda gösterildiği gibi aynı modeli izleyerek bağlantıyı tanımlamanız gerekir. Ancak bunu idMLBindingTable::BindOutputs çağrısıyla işleç başlatıcınızın bağlama tablosuna ekleyin çünkü kalıcı kaynağı başlatmak işleç başlatıcının işidir. Ardından , IDMLBindingTable::BindPersistentResource çağrısıyla derlenmiş işlecinizin bağlama tablosuna ekleyin. Bu iş akışının nasıl çalıştığını görmek için en düşük DirectML uygulama kodu örneğine bakın. Derlenen işleç olduğu sürece kalıcı kaynağın içeriği ve ömrü kalıcı olmalıdır. Başka bir ifadeyle, bir işleç kalıcı bir kaynak gerektiriyorsa, uygulamanızın başlatma sırasında bu kaynağı sağlaması ve daha sonra da içeriğini değiştirmeden işlecin gelecekteki tüm yürütmelerine sağlaması gerekir. Kalıcı kaynak genellikle DirectML tarafından bir işlecin başlatılması sırasında hesaplanan ve bu işlecin gelecekteki yürütmelerinde yeniden kullanılan arama tablolarını veya diğer uzun ömürlü verileri depolamak için kullanılır. Kalıcı arabelleğe bağlı olması için sağlanan arabellek aralığının başlangıç uzaklığının DML_PERSISTENT_BUFFER_ALIGNMENT hizalanmış olması gerekir. Arabelleğin temelindeki yığının türü D3D12_HEAP_TYPE_DEFAULT olmalıdır.

Herhangi bir tensoru açıklayın ve bağlayın.

Derlenmiş bir işleçle (işleç başlatıcısı yerine) ilgileniyorsanız, giriş ve çıkış kaynaklarını (tensorlar ve diğer parametreler için) işlecin bağlama tablosuna bağlamanız gerekir. Bağlama sayısı, isteğe bağlı tensorlar da dahil olmak üzere işlecin giriş sayısıyla tam olarak eşleşmelidir. Bir işlecin aldığı belirli giriş ve çıkış tensorları ve diğer parametreler söz konusu işleç için konu başlığında belgelenmiştir (örneğin , DML_ELEMENT_WISE_IDENTITY_OPERATOR_DESC).

Tensor kaynağı, tensor'un tek tek öğe değerlerini içeren bir arabellektir. Normal Direct3D 12 tekniklerini (Kaynakları karşıya yükleme ve bir arabellek aracılığıyla verileri geri okumak) kullanarak böyle bir arabelleği GPU'ya karşıya yükleyip geri okursunuz. Bu tekniklerin nasıl çalıştığını görmek için en düşük DirectML uygulama kodu örneğine bakın.

Son olarak, DML_BUFFER_BINDING ve DML_BINDING_DESC yapılarıyla giriş ve çıkış kaynak bağlamalarınızı açıklayın ve bunları IDMLBindingTable::BindInputs ve IDMLBindingTable::BindOutputs çağrılarıyla derlenen işlecin bağlama tablosuna ekleyin. IDMLBindingTable::Bind* yöntemini çağırdığınızda, DirectML bir veya daha fazla tanımlayıcıyı CPU tanımlayıcıları aralığına yazar.

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);

DirectML işleci oluşturma adımlarından biri (bkz . IDMLDevice::CreateOperator), işlecin aldığı ve döndürdüğü tensor veri arabelleklerini açıklamak için bir veya daha fazla DML_BUFFER_TENSOR_DESC yapısı bildirmektir. Tensor arabelleğinin türü ve boyutuna ek olarak, isteğe bağlı olarak DML_TENSOR_FLAG_OWNED_BY_DML bayrağını belirtebilirsiniz.

DML_TENSOR_FLAG_OWNED_BY_DML , tensor verilerinin DirectML tarafından sahip olunması ve yönetilmesi gerektiğini belirtir. DirectML, işlecin başlatılması sırasında tensor verilerinin bir kopyasını alır ve kalıcı kaynakta depolar. Bu, DirectML'nin tensor verilerini başka, daha verimli formlara yeniden biçimlendirmesini sağlar. Bu bayrağın ayarlanması performansı artırabilir, ancak genellikle yalnızca verileri işlecin kullanım ömrü boyunca değişmeyen tensörler için yararlıdır (örneğin, ağırlık tensorları). Ayrıca bayrak yalnızca giriş tensorlarında kullanılabilir. Bayrak belirli bir tensor açıklamasında ayarlandığında, ilgili tensor yürütme sırasında değil işleç başlatma sırasında bağlama tablosuna bağlanmalıdır (bu bir hataya neden olur). Bu, varsayılan davranışın (DML_TENSOR_FLAG_OWNED_BY_DML bayrağı olmayan) tersidir; burada tensorun yürütme sırasında bağlanması beklenir, başlatma sırasında değil. DirectML'ye bağlı tüm kaynaklar DEFAULT veya CUSTOM yığın kaynakları olmalıdır.

Daha fazla bilgi için bkz. IDMLBindingTable::BindInputs ve IDMLBindingTable::BindOutputs.

Gönderilebilir unsuru yürütme

IDMLCommandRecorder::RecordDispatch çağrısı yaptığınızda bağlama tablonuzu parametre olarak geçirin.

IDMLCommandRecorder::RecordDispatch çağrısı sırasında bağlama tablosunu kullandığınızda, DirectML ilgili GPU tanımlayıcılarını işlem hattına bağlar. CPU ve GPU tanımlayıcısı tanıtıcıları, tanımlayıcı yığınındaki aynı girişleri işaret etmek için gerekli değildir, ancak bu bağlama tablosunu kullanarak yürütmeden önce CPU tanımlayıcı tutamacı tarafından başvuruda bulunılan tanımlayıcı aralığının tamamının GPU tanımlayıcı tutamacı tarafından başvuruda bulunılan aralığa kopyalandığından emin olmak uygulamanızın sorumluluğundadır.

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()
);

Son olarak, Direct3D 12 komut listenizi kapatın ve diğer komut listelerine yaptığınız gibi yürütme için gönderin.

GPU'da RecordDispatch yürütmeden önce, tüm ilişkili kaynakları D3D12_RESOURCE_STATE_UNORDERED_ACCESS durumuna veya D3D12_RESOURCE_STATE_COMMON gibi örtük olarak D3D12_RESOURCE_STATE_UNORDERED_ACCESS tanıtılabilir bir duruma geçirmelisiniz. Bu çağrı tamamlandıktan sonra kaynaklar D3D12_RESOURCE_STATE_UNORDERED_ACCESS durumunda kalır. Karşıya yükleme yığınları için tek istisna, bir işleç başlatıcı çalıştırılırken ve bir veya daha fazla tensorda DML_TENSOR_FLAG_OWNED_BY_DML bayrağı ayarlanmış olduğunda geçerlidir. Bu durumda, girişe bağlı tüm karşıya yükleme yığınları D3D12_RESOURCE_STATE_GENERIC_READ durumunda olmalıdır ve tüm karşıya yükleme yığınlarının gerektirdiği şekilde bu durumda kalır. İşleç derlenirken DML_EXECUTION_FLAG_DESCRIPTORS_VOLATILE ayarlanmamışsa, RecordDispatch çağrılmadan önce bağlama tablosunda tüm bağlamaların ayarlanması gerekir; aksi takdirde davranış tanımlanmamış olur. Aksi takdirde, bir işleç geç bağlamayı destekliyorsa, Direct3D 12 komut listesi yürütülmek üzere komut kuyruğuna gönderilene kadar kaynakların bağlanması ertelenebilir.

RecordDispatch, ID3D12GraphicsCommandList::Dispatch çağrısı gibi mantıksal olarak işlev görür. Bu nedenle, gönderimler arasında veri bağımlılıkları varsa doğru sıralamayı sağlamak için sıralanmamış erişim görünümü (UAV) engelleri gereklidir. Bu yöntem, giriş veya çıkış kaynaklarına UAV engelleri eklemez. Uygulamanız, içerikleri bir yukarı akış gönderime bağlıysa tüm girişlerde ve bu çıkışlara bağlı aşağı akış gönderimleri varsa çıkışlarda doğru UAV engellerinin gerçekleştirildiğinden emin olmalıdır.

Tanımlayıcıların ve bağlama tablosunun yaşam süresi ve senkronizasyonu

DirectML'de bağlamanın iyi bir zihinsel modeli, arka planda DirectML bağlama tablosunun sağladığınız tanımlayıcı yığını içinde sıralanmamış erişim görünümü (UAV) tanımlayıcıları oluşturup yönetmesidir. Bu nedenle, her zamanki Direct3D 12 kurallarının tümü, bu yığına ve tanımlayıcılarına erişimi eşitlemek için geçerlidir. Bağlama tablosu kullanan CPU ve GPU işleri arasında doğru eşitleme gerçekleştirmek uygulamanızın sorumluluğundadır.

Tanımlayıcı kullanımdayken bağlama tablosu tanımlayıcının üzerine yazamaz (örneğin, önceki bir çerçeve tarafından). Bu nedenle, zaten bağlı olan bir tanımlayıcı yığınını yeniden kullanmak istiyorsanız (örneğin, kendisine işaret eden bir bağlama tablosunda bind* öğesini yeniden çağırarak veya tanımlayıcı yığınının üzerine el ile yazarak) GPU'da yürütmeyi tamamlamak için şu anda tanımlayıcı yığınını kullanan gönderilebilir öğeyi beklemeniz gerekir. Bağlama tablosu, yazmakta olduğu tanımlayıcı yığınında güçlü bir referans sağlamaz, bu nedenle bu bağlama tablosunu kullanan tüm çalışmalar GPU'da yürütmeyi tamamlayana kadar gölgelendirici görünür tanımlayıcı yığınını serbest bırakmamalısınız.

Öte yandan, bağlama tablosu tanımlayıcı yığınını belirtip yönetirken, tablonun kendisi bu belleğin hiçbirini içermez . Bu nedenle, IDMLCommandRecorder::RecordDispatch çağrısı yaptıktan sonra bağlama tablosunu istediğiniz zaman serbest bırakabilirsiniz veya sıfırlayabilirsiniz (temel alınan tanımlayıcılar geçerli kaldığı sürece GPU'da bu çağrının tamamlanmasını beklemeniz gerekmez).

Bağlama tablosu, üzerindeki kaynaklara güçlü referanslar tutmaz; uygulamanız, kaynakların GPU tarafından hâlâ kullanıldığı süre boyunca silinmediğinden emin olmalıdır. Ayrıca bağlama tablosu iş parçacığı açısından güvenli değildir; uygulamanız eşitleme olmadan farklı iş parçacıklarından aynı anda bağlama tablosundaki yöntemleri çağırmamalıdır.

Ayrıca, her durumda yalnızca hangi kaynakların bağlı olduğunu değiştirdiğinizde yeniden bağlamanın gerekli olduğunu düşünün. İlişkili kaynakları değiştirmeniz gerekmiyorsa başlangıçta bir kez bağlanabilir ve RecordDispatch'i her çağırdığınızda aynı bağlama tablosunu geçirebilirsiniz.

Makine öğrenimi ve render iş yüklerinin iç içe geçirilmesi için, her çerçevenin bağlama tablolarının, GPU'da henüz kullanılmayan tanımlayıcı yığını aralıklarına işaret ettiğinden emin olun.

İsteğe bağlı olarak, geç bağlanan işleç bağlamalarını belirtin

Derlenmiş işleçle (işleç başlatıcısı yerine) ilgileniyorsanız, işleç için geç bağlama belirtme seçeneğiniz vardır. Geç bağlama olmadan, bir işleci bir komut listesine kaydetmeden önce bağlama tablosundaki tüm bağlamaları ayarlamanız gerekir. Geç bağlama ile, komut kuyruğuna gönderilmeden önce zaten bir komut listesine kaydettiğiniz işleçlerde bağlamalar ayarlayabilir (veya değiştirebilirsiniz).

Geç bağlamayı belirtmek için, DML_EXECUTION_FLAG_DESCRIPTORS_VOLATILE bağımsız değişkeniyle flagsIDMLDevice::CompileOperator çağrısı yapın.

Ayrıca bakınız