Извините, я был занят и сделал несколько ошибок. Во -первых, логика для различных реализаций была не то же самое, и я соответствующим образом скорректировал, что есть переполнение с плаванием, и я изменил его на удвоение. Теперь я обновил ниже код, чтобы проверить различные параметры 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
Почему std :: execution :: par_unseq медленно по сравнению с другими параллельными параметрами ⇐ C++
Программы на C++. Форум разработчиков
1752085114
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[i] = 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[i];
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)
Подробнее здесь: [url]https://stackoverflow.com/questions/79695505/why-is-stdexecutionpar-unseq-slow-compared-with-other-parallel-options[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия