Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
paralel ParallelHelper kodla çalışmak için yüksek performanslı API'ler içerir. Belirli bir veri kümesi veya yineleme aralığı veya alanı üzerinde paralel işlemleri hızlı bir şekilde ayarlamak ve yürütmek için kullanılabilecek performans odaklı yöntemler içerir.
Platform API'leri:
ParallelHelper,IAction,IAction2D,IRefAction<T>,IInAction<T>
Nasıl çalışır?
ParallelHelper tür üç ana kavram etrafında oluşturulur:
- Hedef yineleme aralığı üzerinde otomatik toplu işlem gerçekleştirir. Bu, kullanılabilir CPU çekirdeklerinin sayısına göre doğru sayıda çalışma birimini otomatik olarak zamanlaması anlamına gelir. Bu, her paralel yineleme için paralel geri çağırma yükünü bir kez azaltmak için yapılır.
- C# dilinde genel türlerin uygulanma biçiminden büyük ölçüde yararlanıyor ve gibi
structtemsilciler yerine belirli arabirimleri uygulayan türleri kullanıyorAction<T>. Bu, JIT derleyicisinin kullanılan her bir geri çağırma türünü "görebilmesi" için yapılır ve bu sayede geri çağırmayı mümkün olduğunda tamamen satır içi olarak satır içi hale getirmek mümkün olur. Bu, özellikle çok küçük geri çağırmalar kullanıldığında her paralel yinelemenin yükünü büyük ölçüde azaltabilir ve bu da yalnızca temsilci çağrısı açısından önemsiz bir maliyete neden olur. Ayrıca, bir türü geri çağırma olarak kullanmakstruct, geliştiricilerin kapanışta yakalanan değişkenleri el ile işlemesini gerektirir ve bu da işaretçininthisörnek yöntemlerinden ve her geri çağırma çağrısını önemli ölçüde yavaşlatabilecek diğer değerlerden yanlışlıkla yakalanmasını önler. Bu, gibiImageSharpdiğer performans odaklı kitaplıklarda kullanılan yaklaşımla aynıdır. - 4 farklı yineleme türünü temsil eden 4 tür API'yi kullanıma sunar: 1B ve 2B döngüler, yan etkisi olan öğeler yinelemesi ve yan etkisi olmayan öğeler yinelemesi. Her eylem türünün, API'lere geçirilen geri çağırmalara uygulanması gereken karşılık gelen
interfacebir türü vardır: ,structParallelHelperIActionve .IAction2DIRefAction<T>IInAction<T><T>Bu, geliştiricilerin amacıyla ilgili daha net bir kod yazmasına yardımcı olur ve API'lerin dahili olarak daha fazla iyileştirme gerçekleştirmesine olanak tanır.
Sözdizimi
Bir float[] dizideki tüm öğeleri işlemek ve bunların her birini ile 2çarpmak istediğimizi düşünelim. Bu durumda herhangi bir değişken yakalamamız gerekmez: yalnızca öğesini kullanabiliriz IRefAction<T>interface ve ParallelHelper geri çağırmamıza otomatik olarak beslemek için her öğeyi yükleyeceğiz. Tek gereken, bir ref float bağımsız değişken alacak ve gerekli işlemi gerçekleştirecek geri çağırmamızı tanımlamaktır:
// Be sure to include this using at the top of the file:
using Microsoft.Toolkit.HighPerformance.Helpers;
// First declare the struct callback
public readonly struct ByTwoMultiplier : IRefAction<float>
{
public void Invoke(ref float x) => x *= 2;
}
// Create an array and run the callback
float[] array = new float[10000];
ParallelHelper.ForEach<float, ByTwoMultiplier>(array);
API ile ForEach yineleme aralıklarını belirtmemiz gerekmez: ParallelHelper koleksiyonu toplu işler ve her giriş öğesini otomatik olarak işler. Ayrıca, bu özel örnekte bağımsız değişken olarak geçirmemiz struct bile gerekmemiştir: başlatmamız gereken alan olmadığından, yalnızca öğesini çağırırken ParallelHelper.ForEachtürünü tür bağımsız değişkeni olarak belirtebiliriz: bu API bunun yeni bir örneğini struct kendi başına oluşturur ve bunu çeşitli öğeleri işlemek için kullanır.
Kapanış kavramını tanıtmak için dizi öğelerini çalışma zamanında belirtilen bir değerle çarpmak istediğimizi varsayalım. Bunu yapmak için geri struct çağırma türümüzde bu değeri "yakalamamız" gerekir. Bunu şu şekilde yapabiliriz:
public readonly struct ItemsMultiplier : IRefAction<float>
{
private readonly float factor;
public ItemsMultiplier(float factor)
{
this.factor = factor;
}
public void Invoke(ref float x) => x *= this.factor;
}
// ...
ParallelHelper.ForEach(array, new ItemsMultiplier(3.14f));
artık öğesinin struct bir sabit kullanmak yerine öğeleri çarpmak için kullanmak istediğimiz faktörü temsil eden bir alan içerdiğini görebiliriz. çağrılırken ForEach, ilgilendiğimiz faktörle açıkça geri çağırma türümüzün bir örneğini oluşturuyoruz. Ayrıca, bu durumda C# derleyicisi de kullanmakta olduğumuz tür bağımsız değişkenlerini otomatik olarak tanıyabilir, böylece bunları yöntem çağrısından birlikte atlayabiliriz.
Geri çağırmadan erişmemiz gereken değerler için alanlar oluşturma yaklaşımı, hangi değerleri yakalamak istediğimizi açıkça bildirmemize olanak tanır ve bu da kodun daha etkileyici olmasına yardımcı olur. Bu, bazı yerel değişkenlere erişen bir lambda işlevi veya yerel işlev bildirdiğimizde C# derleyicisinin arka planda yaptığı işlemle tamamen aynıdır.
Bu kez bir dizinin tüm öğelerini paralel olarak başlatmak için API'yi kullanan For başka bir örnek aşağıda verilmiştir. Bu kez hedef diziyi doğrudan yakaladığımıza ve yöntemimize bağımsız değişken olarak geçerli paralel yineleme dizinini IActioninterface veren geri çağırma için öğesini nasıl kullandığımıza dikkat edin:
public readonly struct ArrayInitializer : IAction
{
private readonly int[] array;
public ArrayInitializer(int[] array)
{
this.array = array;
}
public void Invoke(int i)
{
this.array[i] = i;
}
}
// ...
ParallelHelper.For(0, array.Length, new ArrayInitializer(array));
Not
Geri çağırma türleri struct-s olduğundan, bunlar başvuruyla değil paralel çalışan her iş parçacığına kopya yoluyla geçirilir. Bu, geri çağırma türlerinde alan olarak depolanan değer türlerinin de kopyalanacağı anlamına gelir. C# derleyicisinin alanlarının değerlerini değiştirmemize izin vermemesi için, bu ayrıntıyı anımsamak ve hatalardan kaçınmak için geri struct çağırmayı olarak readonlyişaretlemek iyi bir uygulamadır. Bu yalnızca bir değer türünün örnek alanları için geçerlidir: Bir geri struct çağırmanın herhangi bir türde alanı static veya başvuru alanı varsa, bu değer paralel iş parçacıkları arasında doğru şekilde paylaşılır.
Yöntemler
Bunlar, tarafından ParallelHelperkullanıma sunulan, , IActionIAction2D ve IRefAction<T> arabirimlerine IInAction<T>karşılık gelen 4 ana API'dir. Türü ParallelHelper , yineleme aralıklarını veya giriş geri çağırma türünü belirtmenin çeşitli yollarını sunan bu yöntemler için bir dizi aşırı yükleme de sunar.
For ve For2D üzerinde ve örnekleri üzerinde IActionIAction2D çalışır ve bunların, her paralel yinelemenin dizinleriyle doğrudan erişilebilen temel alınan bir koleksiyonla eşlenmesi gerekmeyen bazı paralel çalışmaların yapılması gerektiğinde kullanılması amaçlanır. ve ForEach örnekleri yerine aşırı IRefAction<T> yükler ve IInAction<T> paralel yinelemeler doğrudan dizine alınabilen bir koleksiyondaki öğelerle eşlendiğinde kullanılabilir. Bu durumda da dizin oluşturma mantığını soyutlarlar, böylece her paralel çağrının yalnızca üzerinde çalışılması gereken giriş öğesi üzerinde endişelenmesi gerekir ve bu öğenin nasıl alınıp alınmadığını da dikkate alır.
Örnekler
.NET Community Toolkit