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

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

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[i] << ' ';
    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

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[i] << ' ';
    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ü

İ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>>

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


(RME)


Yayımlandı

kategorisi

yazarı:

Etiketler:

Yorumlar

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir