C ++ 26'da paralel veri türleri: İşlemlerin koşullu yürütülmesi

Saberie

Active member
Ne yazık ki, son yazımda “C ++ 26'daki paralel veri türleri: Uygulamanın Bir Örneği” yeni kütüphanenin bir fonksiyonunu sunmayı unuttu. Bu makaleye ekleyeceğim.






Rainer Grimm




Rainer Grimm yıllardır yazılım mimarı, ekip ve eğitim müdürü olarak çalıştı. C ++ programlama dilleri, Python ve Haskell hakkında makaleler yazmayı seviyor, ancak uzman konferanslarla konuşmayı da seviyor. Modern C ++ blogunda, C ++ tutkusuyla yoğun bir şekilde ilgileniyor.








İfade nerede


Yeni anahtar kelime where So -Called bir ifade oluşturun. Bu, bir SIMD taşıyıcının öğelerinin sınırlı ölçüde karşılaşabileceği anlamına gelir.

Aşağıdaki örnek bu davranışı özetlemektedir:



// where.cpp

#include <experimental/simd>
#include <iostream>
#include <string_view>
namespace stdx = std::experimental;

void println(std::string_view name, auto const& a)
{
std::cout << name << ": ";
for (std::size_t i{}; i != std::size(a); ++i)
std::cout << a << ' ';
std::cout << 'n';
}

template<class A>
stdx::simd<int, A> my_abs(stdx::simd<int, A> x)
{
where(x < 0, x) = -x; // Set elements where x is negative to their absolute value
return x;
}

int main()
{
const stdx::native_simd<int> a = 1;
println("a", a);

const stdx::native_simd<int> b([](int i) { return i - 2; });
println("b", b);

const auto c = a + b;
println("c", c);

const auto d = my_abs(c);
println("d", d);

}


İşlevde my_abs geliyor where-Kullanılacak Fonksiyon: where(x < 0, x) = -x; SIMD taşıyıcısının sıfırdan daha düşük olan tüm unsurlarının mutlak değerlerine yerleştirildiği anlamına gelir.







Kod örneği



Ekran görüntüsü örnek kodun sürümünü gösterir.



Bu durumda, SSE2 komutları kullanılır. SIMD vektörü 128 bittir.

. where-Presyon biriyle olabilir bool-Press veya bir simd_mask parametrelendirilmiş olun.

Yukarıdaki kod örneği, bir tane ile de kullanılabilir. simd_mask alet. Aşağıdaki kod uygulamayı gösterir:



// whereMask.cpp

#include <experimental/simd>
#include <iostream>
#include <string_view>
namespace stdx = std::experimental;

void println(std::string_view name, auto const& a)
{
std::cout << std::boolalpha << name << ": ";
for (std::size_t i{}; i != std::size(a); ++i)
std::cout << a << ' ';
std::cout << 'n';
}


int main()
{
const stdx::native_simd<int> a = 1;
println("a", a);

const stdx::native_simd<int> b([](int i) { return i - 2; });
println("b", b);

const auto c = a + b;
println("c", c);

const stdx::native_simd_mask x = c < 0;
println("x", x);

auto d = c;
where(x, d) *= -1;
println("d", d);

}


Açıklamamı ana işlevin son beş satırı ile başlatmak istiyorum. Önce yaratıyorum simd_mask x yüklemle c < 0 SIMD C. Vector'un her bir öğesine uygulanır

Maske X, SIMD taşıyıcısı ile aynı uzunluğa sahiptir, ancak sadece gerçek değerleri vardır. Böylece bu gerçeklerin değerleri gibi true VEYA false Ve 1 veya 0 olarak gösterilmiyorlar, işlevim var println . Streammanipulator std::boolalpha Eklendi.

Ayrıca, C sabit olduğu için SIMD D taşıyıcısını C ile başlatmalıyım. Şimdi ifade olabilir where(x, d) *= -1; Maske değeri Maske olduğunda SIMD vektörünün her öğesi iptal edilir. true mal sahibi.





İkinci kodun ekran görüntüsü sürümü



Ekran görüntüsü, kodun SIMD_MASK ile sürümünü gösterir.



Veri türü simd_mask Veri türüdür simd çok benzer. Temel fark şu ki simd Tüm standart türleri, çizim türlerini ve türlerini yüzebilir ve çift alabilir. Aksine, desteklendi simd_mask Sadece gerçek değerler.

Tanımı simd_mask Görünüşe göre:



template<size_t Bytes, class Abi>
class basic_simd_mask


Abbi, öğelerin sayısını ve depolama alanlarını belirlediği gün. Lise tarihleri yine bütünlük içindir:

  • scalar: Tek bir öğeyi kaydedin
  • fixed_size: Bir dizi öğeyi kaydedin
  • compatible: ABI'nin uyumluluğunu garanti eder
  • native: daha verimli
  • max_fixed_size: Fixe_size tarafından garanti edilen maksimum öğe sayısı
Saniye simd Ha simd_mask Ayrıca iki Aliase:



template< size_t Bytes, int N >
using fixed_size_simd_mask = simd_mask<Bytes, simd_abi::fixed_size<N>>

template< size_t Bytes >
using native_simd_mask = simd_mask<Bytes, simd_abi::native<Bytes>>


Sırada ne var?


Paralel veri türleri hakkındaki son makalemde, bunun için özel işlevlere yanıt vermek istiyorum.


(RME)




Ne yazık ki, bu bağlantı artık geçerli değil.

Boşa harcanan eşyalara olan bağlantılar, 7 günlük daha büyükse veya çok sık çağrılmışsa gerçekleşmez.


Bu makaleyi okumak için bir Haberler+ paketine ihtiyacınız var. Şimdi yükümlülük olmadan bir hafta deneyin – yükümlülük olmadan!
 
Üst