Почему std :: execution :: par_unseq медленно по сравнению с другими параллельными параметрамиC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Почему std :: execution :: par_unseq медленно по сравнению с другими параллельными параметрами

Сообщение Anonymous »

Извините, я был занят и сделал несколько ошибок. Во -первых, логика для различных реализаций была не то же самое, и я соответствующим образом скорректировал, что есть переполнение с плаванием, и я изменил его на удвоение. Теперь я обновил ниже код, чтобы проверить различные параметры SIMD для Monte Carlo Progam. Результат выясняется, что std :: execution :: par_unseq дал самый медленный и другой результат. < /P>
------------------------------------------------------------------------------------------------------
Benchmark Time CPU Iterations UserCounters...
------------------------------------------------------------------------------------------------------
SimdFixture/black_scholes_mc_scalar 584217000 ns 584210200 ns 1 check_pv=10.4515
SimdFixture/black_scholes_mc_parallel 802403100 ns 802393700 ns 1 check_pv=10.2335
SimdFixture/black_scholes_mc_parallel_unseq 778954000 ns 778946000 ns 1 check_pv=8.322
SimdFixture/black_scholes_mc_simd_c23 601620500 ns 600948400 ns 1 check_pv=10.4515
SimdFixture/black_scholes_mc_simd_avx 466860950 ns 466861050 ns 2 check_pv=10.4191
< /code>
main.cpp
#include "aligned_allocator.h"
#include
#include
#include
#include
#include // For C++17 parallel policies, or use simd with experimental::simd in C++23
#include
#include // AVX intrinsics
#include
#include
#include
#include

typedef std::vector AlignedVector;

class SimdFixture : public benchmark::Fixture {
protected:
const int N = 100'000'000;
std::vector zs;
float S0 = 100.0f, K = 100.0f, T = 1.0f, r = 0.05f, sigma = 0.2f;

void SetUp(const ::benchmark::State &state) override {
zs.resize(N);
std::default_random_engine gen;
std::normal_distribution dist(0.0, 1.0);
for (int i = 0; i < N; ++i)
zs = dist(gen);
}
};

BENCHMARK_F(SimdFixture, black_scholes_mc_scalar)(benchmark::State &state) {
for (auto _ : state) {
double pv = 0.0;
double payoff_sum = 0.0f;
float drift = (r - 0.5f * sigma * sigma) * T;
float diffusion = sigma * std::sqrt(T);
for (int i = 0; i < N; ++i) {
float Z = zs;
float ST = S0 * std::exp(drift + diffusion * Z);
payoff_sum += std::max(ST - K, 0.0f);
}
pv = std::exp(-r * T) * (payoff_sum / N);
benchmark::DoNotOptimize(pv);
state.counters["check_pv"] = pv;
}
}

BENCHMARK_F(SimdFixture, black_scholes_mc_parallel)(benchmark::State &state) {
for (auto _ : state) {
double pv = 0.0;
std::vector payoff(N);
float drift = (r - 0.5f * sigma * sigma) * T;
float diffusion = sigma * std::sqrt(T);
std::transform(std::execution::par, zs.begin(), zs.end(), payoff.begin(),
[&](float z) {
float ST = S0 * std::exp(drift + diffusion * z);
return std::max(ST - K, 0.0f);
});

double sum = std::reduce(std::execution::par, payoff.begin(), payoff.end());
pv = std::exp(-r * T) * (sum / N);
benchmark::DoNotOptimize(pv);
state.counters["check_pv"] = pv;
}
}

BENCHMARK_F(SimdFixture, black_scholes_mc_parallel_unseq)
(benchmark::State &state) {
for (auto _ : state) {
double pv = 0.0;
std::vector payoff(N);
float drift = (r - 0.5f * sigma * sigma) * T;
float diffusion = sigma * std::sqrt(T);
std::transform(std::execution::par_unseq, zs.begin(), zs.end(),
payoff.begin(), [&](float z) {
float ST = S0 * std::exp(drift + diffusion * z);
return std::max(ST - K, 0.0f);
});

double sum =
std::reduce(std::execution::par_unseq, payoff.begin(), payoff.end());
pv = std::exp(-r * T) * (sum / N);
benchmark::DoNotOptimize(pv);
state.counters["check_pv"] = pv;
}
}

namespace stdx = std::experimental;
BENCHMARK_F(SimdFixture, black_scholes_mc_simd_c23)(benchmark::State &state) {
for (auto _ : state) {
double pv = 0.0;
using simd_t = stdx::native_simd;
constexpr std::size_t W = simd_t::size(); // SIMD width

simd_t sum = 0.0f;
size_t i = 0;

float drift = (r - 0.5f * sigma * sigma) * T;
float diffusion = sigma * std::sqrt(T);

for (; i + W
cmakelists: < /p>
cmake_minimum_required(VERSION 3.10)
project(test_simd)

set(CMAKE_CXX_STANDARD 23) # or 20, 23, etc.
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -march=native -mavx -ftree-vectorize -fopt-info-vec")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -march=native")
find_package(benchmark REQUIRED)
add_executable(test_simd main.cpp test_simd_execution_par.cpp)
target_link_libraries(test_simd PRIVATE benchmark::benchmark)


Подробнее здесь: https://stackoverflow.com/questions/796 ... el-options
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»