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.
İ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[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.
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.
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 kaydedinfixed_size
: Bir dizi öğeyi kaydedincompatible
: ABI'nin uyumluluğunu garanti edernative
: daha verimlimax_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)
Bir yanıt yazın