extern "C" __declspec(dllexport) __declspec(noalia...
作成日: 2025年10月2日
使用モデル GPT-5 Thinking by Chat01
作成日: 2025年10月2日
使用モデル GPT-5 Thinking by Chat01
extern "C" __declspec(dllexport) __declspec(noalias) void Base_LNA_1_2_Mer_AGP(
const float N, const float global_iterations, const float a, const float b, const float c, const float d, const float r,
const bool mode, const float epsilon, const float seed,
float** __restrict out_data, size_t* __restrict out_len) noexcept
{
if (N == 1.0f) {
// === Базовая геометрия интервала и пороги ===
const float initial_length = b - a;
float dmax = initial_length;
const float threshold_03 = 0.3f * initial_length;
const float inv_threshold_03 = 1.0f / threshold_03;
text// === Стартовые оценки функции на краях === const float start_val = ShekelFunc(a, seed); float best_f = ShekelFunc(b, seed); // === «Горячая» четвёрка max-интервала === float x_Rmax_1 = a; float x_Rmax_2 = b; float y_Rmax_1 = start_val; float y_Rmax_2 = best_f; // === Контейнеры под результаты и кучу интервалов === Extr.reserve(global_iterations * 4u); // REORDER: выше clear Extr.clear(); R.reserve(global_iterations * 2u); R.clear(); // === Начальный интервал и параметры m/M === R.emplace_back(std::make_unique<Interval>(&a, &b, &start_val, &best_f, &N)); std::push_heap(R.begin(), R.end(), ComparePtr); float Mmax = *R.front()->M; float m = r * Mmax; // === ВЫНЕСЕННЫЕ ПЕРЕД ЦИКЛОМ ПЕРЕМЕННЫЕ === int schetchick = 0; // 1) Временные переменные для работы с интервалами float x1, y1, x2, y2, new_point, new_value; std::unique_ptr<Interval> promejutochny_otrezok; // 2) Временные для новых интервалов std::unique_ptr<Interval> curr, curr1; float currM = 0; size_t r_size = 0; float len2, len1, dmin; // 3) Временные для пересчета характеристик float progress, alpha, betta, MULTIPLIER, global_coeff, GLOBAL_FACTOR; // 4) Вспомогательные переменные const std::unique_ptr<Interval>* top_ptr; float len_item; while (true) { // ... ТЕЛО ЦИКЛА БЕЗ ИЗМЕНЕНИЙ ... // Используются вынесенные переменные, которые перезаписываются каждую итерацию new_point = Shag(m, x_Rmax_1, x_Rmax_2, y_Rmax_1, y_Rmax_2, N, r); new_value = ShekelFunc(new_point, seed); if (new_value < best_f) { best_f = new_value; Extr.emplace_back(best_f); Extr.emplace_back(new_point); } std::pop_heap(R.begin(), R.end(), ComparePtr); promejutochny_otrezok = std::move(R.back()); // promejutochny_otrezok перезаписывается x1 = *promejutochny_otrezok->x1; // x1, y1, x2, y2 перезаписываются y1 = *promejutochny_otrezok->y1; x2 = *promejutochny_otrezok->x2; y2 = *promejutochny_otrezok->y2; R.pop_back(); r_size = R.size(); // r_size перезаписывается len2 = x2 - new_point; len1 = new_point - x1; dmin = len1 < len2 ? len1 : len2; if (++schetchick == global_iterations || dmin < epsilon) { if (g_world->rank() == 0) { Extr.emplace_back(schetchick); Extr.emplace_back(dmin); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } curr = std::make_unique<Interval>(&x1, &new_point, &y1, &new_value, &N); curr1 = std::make_unique<Interval>(&new_point, &x2, &new_value, &y2, &N); currM = *curr->M > *curr1->M ? *curr->M : *curr1->M; if (len2 + len1 == dmax) { dmax = len2 > len1 ? len2 : len1; size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
len_item = *R[i]->x2 - *R[i]->x1;
if (len_item > dmax) {
dmax = len_item;
}
++i;
}
}
textif (mode) { if (threshold_03 > dmax && fmodf(schetchick, 3.0f) == 0.0f || 10.0f * dmax < initial_length) { if (currM > Mmax) { Mmax = currM; m = r * Mmax; } progress = fmaf(-inv_threshold_03, dmax, 1.0f); alpha = fmaf(progress, progress, 1.0f); betta = 2.0f - alpha; MULTIPLIER = (1.0f / dmax) * Mmax; global_coeff = fmaf(MULTIPLIER, r, -MULTIPLIER); GLOBAL_FACTOR = betta * global_coeff; curr->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len1, *curr->M * alpha)); curr1->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len2, *curr1->M * alpha)); size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, *R[i]->x2 - *R[i]->x1, *R[i]->M * alpha));
++i; // Increment moved inside the loop body
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(m);
++i;
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
}
}
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(m);
++i;
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
}
}
text// Добавляем новые интервалы R.emplace_back(std::move(curr)); std::push_heap(R.begin(), R.end(), ComparePtr); R.emplace_back(std::move(curr1)); std::push_heap(R.begin(), R.end(), ComparePtr); // Обновление x_Rmax и y_Rmax top_ptr = &R.front(); x_Rmax_1 = *(*top_ptr)->x1; x_Rmax_2 = *(*top_ptr)->x2; y_Rmax_1 = *(*top_ptr)->y1; y_Rmax_2 = *(*top_ptr)->y2; } } else { // === Топология процесса/партнёра (используется в каждом обороте) === const int rank = g_world->rank(); const int partner = rank ^ 1; // REORDER: рядом с rank // === Геометрия развёртки и базовые приращения === const float divider = ldexpf(1.0f, (Curve->razvertka << 1) + 1); const float inv_divider = 1.0f / divider; // REORDER: сразу за divider const float x_addition = (b - a) * inv_divider; const float y_addition = (d - c) * inv_divider; // === Истинные границы по оси развёртки и их производные === const float true_start = a + x_addition; const float true_end = b - x_addition; // Пара «максимальный интервал» по X (часто читается Shag) — // держим рядом для локальности со связанными Y-значениями float x_Rmax_1 = true_start; // REORDER float x_Rmax_2 = true_end; // REORDER // === Длины/пороги, используемые в каждом обороте === const float initial_length = true_end - true_start; float dmax = initial_length; // REORDER: рядом с initial_length const float threshold_03 = 0.3f * initial_length; const float inv_threshold_03 = 1.0f / threshold_03; // === Стартовые значения функции и «горячая» пара y_Rmax/best_f === const float end_val = rank ? RastriginFunc(true_end, d - y_addition) : RastriginFunc(true_start, c + y_addition); float y_Rmax_1 = end_val; // REORDER: сразу за end_val float best_f = rank ? RastriginFunc(true_start, d - y_addition) : RastriginFunc(true_end, c + y_addition); float y_Rmax_2 = best_f; // REORDER: рядом с best_f // === Резервы под контейнеры (до первого использования) === Extr.reserve(global_iterations * 4u); // REORDER: выше clear Extr.clear(); R.reserve(global_iterations * 2u); R.clear(); // === Начальный интервал и его характеристика (сразу после подготовки контейнеров) === R.emplace_back(std::make_unique<Interval>(&true_start, &true_end, &end_val, &best_f, &N)); float Mmax = *R.front()->M; float m = r * Mmax; // === Счётчики цикла / режим (используются часто) === int schetchick = 0; // REORDER: чуть ниже Mmax/m int mcQueenSpeed = 1; // === Горячие локальные переменные цикла, сгруппированы по фазам использования === // 1) Выбор/оценка точки и координаты по Пеано (LNA hotspot) float new_point, new_value; // REORDER: ближе к Shag/RastriginFunc const PeanoCurve_2D* __restrict pc; float new_x1, new_x2; // 2) Работа с кучей интервалов (split/best) std::unique_ptr<Interval> promejutochny_otrezok; std::unique_ptr<Interval> curr; std::unique_ptr<Interval> curr1; float currM; float len2, len1; float len_item; size_t r_size; // 3) Переоценка характеристик / глобальная перенастройка float progress, alpha, betta, MULTIPLIER, global_coeff, GLOBAL_FACTOR; // 4) Доступ к top и критерии (epsilon/длина) const std::unique_ptr<Interval>* __restrict top_ptr; float interval_len; // 5) Коммуникации (MPI hotspot), сгруппированы отдельно boost::optional<boost::mpi::status> probe_status; int dummy; const PeanoCurve_2D* __restrict p1L; const PeanoCurve_2D* __restrict p2L; CrossMsg outbound; CrossMsg inbound; std::unique_ptr<Interval> injected; float newParam1_remote1, newParam2_remote1, newParam1_remote2, newParam2_remote2; // 6) «Охлаждение» и периодика — считаются каждый шаг float cooling, T, k; while (true) { // MPI проверки probe_status = g_world->iprobe(partner, boost::mpi::any_tag); if (probe_status->tag() == 0) { g_world->irecv(partner, 0, mcQueenSpeed); } else if (probe_status->tag() == 2) { g_world->irecv(partner, 2, dummy); if (partner) { top_ptr = &R.front(); Extr.emplace_back(schetchick); Extr.emplace_back(*(*top_ptr)->x2 - *(*top_ptr)->x1); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } // Условие завершения по итерациям if (++schetchick == global_iterations) { g_world->isend(partner, 2, 0); if (partner) { top_ptr = &R.front(); Extr.emplace_back(schetchick); Extr.emplace_back(*(*top_ptr)->x2 - *(*top_ptr)->x1); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } // «Охлаждение» и период T cooling = ldexpf(1.0f, -schetchick * (1.0f / 138.63f)); T = floorf(fmaf(20.0f, cooling, 10.0f)); k = fmaf(0.2f, cooling, 0.7f); if (!(fmodf(schetchick, T)) == mcQueenSpeed) { top_ptr = &R.front(); p1L = Curve->HitTest_2D(*(*top_ptr)->x1); p2L = Curve->HitTest_2D(*(*top_ptr)->x2); outbound = CrossMsg{ p1L->x1, p1L->x2, p2L->x1, p2L->x2, *(*top_ptr)->R }; if (mcQueenSpeed) { g_world->isend(partner, 0, 0); } else { mcQueenSpeed = 1; } g_world->isend(partner, 1, outbound); g_world->irecv(partner, 1, inbound); // Проекция удалённых точек newParam1_remote1 = Curve->FindX_2D(inbound.s_x1, inbound.s_x2); newParam2_remote1 = Curve->FindX_2D(inbound.e_x1, inbound.e_x2); newParam1_remote2 = RastriginFunc(inbound.s_x1, inbound.s_x2); newParam2_remote2 = RastriginFunc(inbound.e_x1, inbound.e_x2); // «Инъекция» с пониженной характеристикой injected = std::make_unique<Interval>(&newParam1_remote1, &newParam2_remote1, &newParam1_remote2, &newParam2_remote2, &N); *injected->R = inbound.Rtop * k; R.emplace_back(std::move(injected)); std::push_heap(R.begin(), R.end(), ComparePtr); } // Локальный шаг LNA new_point = Shag(m, x_Rmax_1, x_Rmax_2, y_Rmax_1, y_Rmax_2, N, r); // Координаты по кривой Пеано pc = Curve->HitTest_2D(new_point); new_x1 = pc->x1; new_x2 = pc->x2; new_value = RastriginFunc(new_x1, new_x2); // Обновление экстремумов if (new_value < best_f) { best_f = new_value; Extr.emplace_back(best_f); Extr.emplace_back(new_x1); Extr.emplace_back(new_x2); } // Разбиение лучшего интервала std::pop_heap(R.begin(), R.end(), ComparePtr); promejutochny_otrezok = std::move(R.back()); R.pop_back(); // Создаём подынтервалы curr = std::make_unique<Interval>(promejutochny_otrezok->x1, &new_point, promejutochny_otrezok->y1, &new_value, &N); curr1 = std::make_unique<Interval>(&new_point, promejutochny_otrezok->x2, &new_value, promejutochny_otrezok->y2, &N); currM = *curr->M > *curr1->M ? *curr->M : *curr1->M; len2 = *promejutochny_otrezok->x2 - new_point; len1 = new_point - *promejutochny_otrezok->x1; r_size = R.size(); if (len2 + len1 == dmax) { dmax = len2 > len1 ? len2 : len1; size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
len_item = *R[i]->x2 - *R[i]->x1;
if (len_item > dmax) {
dmax = len_item;
}
++i;
}
}
textif (mode) { if (threshold_03 > dmax && fmodf(schetchick, 3.0f) == 0.0f || 10.0f * dmax < initial_length) { if (currM > Mmax) { Mmax = currM; m = r * Mmax; } progress = fmaf(-inv_threshold_03, dmax, 1.0f); alpha = fmaf(progress, progress, 1.0f); betta = 2.0f - alpha; MULTIPLIER = (1.0f / dmax) * Mmax; global_coeff = fmaf(MULTIPLIER, r, -MULTIPLIER); GLOBAL_FACTOR = betta * global_coeff; curr->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len1, *curr->M * alpha)); curr1->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len2, *curr1->M * alpha)); size_t i = 0u; // Initialization moved before the loop
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, *R[i]->x2 - *R[i]->x1, *R[i]->M * alpha));
++i; // Increment moved inside the loop body
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(m);
++i;
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
}
}
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(m);
++i;
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
}
}
text// Добавление подынтервалов R.emplace_back(std::move(curr)); std::push_heap(R.begin(), R.end(), ComparePtr); R.emplace_back(std::move(curr1)); std::push_heap(R.begin(), R.end(), ComparePtr); // Проверка критерия сходимости top_ptr = &R.front(); interval_len = *(*top_ptr)->x2 - *(*top_ptr)->x1; if (interval_len < epsilon) { g_world->isend(partner, 2, 0); if (partner) { Extr.emplace_back(schetchick); Extr.emplace_back(interval_len); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } // Обновляем x_Rmax и y_Rmax x_Rmax_1 = *(*top_ptr)->x1; x_Rmax_2 = *(*top_ptr)->x2; y_Rmax_1 = *(*top_ptr)->y1; y_Rmax_2 = *(*top_ptr)->y2; } }
} теперь посмотри на этот метод тут и для 1d и для 2d ветки есть общие переменные - будет ли лучше их вынести из ветвления для лучшей оптимизации по скорости - теоритически это может уменьшить размер бинарного кода - поможет ли это в оптимизации по скорости? Как например я сделал это здесь: extern "C" __declspec(dllexport) __declspec(noalias) void Base_LNA_1_2_Mer_AGP(
const float N, const float global_iterations, const float a, const float b, const float c, const float d, const float r,
const bool mode, const float epsilon, const float seed,
float** __restrict out_data, size_t* __restrict out_len) noexcept
{
const int rank = g_world->rank();
const int partner = rank ^ 1; // REORDER: рядом с rank
text// === Геометрия развёртки и базовые приращения === const float divider = ldexpf(1.0f, (Curve->razvertka << 1) + 1); const float inv_divider = 1.0f / divider; // REORDER: сразу за divider const float x_addition = (b - a) * inv_divider; const float y_addition = (d - c) * inv_divider; // === Истинные границы по оси развёртки и их производные === const float true_start = a + x_addition; const float true_end = b - x_addition; // Пара «максимальный интервал» по X (часто читается Shag) — // держим рядом для локальности со связанными Y-значениями float x_Rmax_1; // REORDER float x_Rmax_2; // REORDER // === Длины/пороги, используемые в каждом обороте === float initial_length; float dmax; // REORDER: рядом с initial_length float threshold_03; float inv_threshold_03; // === Стартовые значения функции и «горячая» пара y_Rmax/best_f === float start_val; float y_Rmax_1; // REORDER: сразу за end_val float best_f; float y_Rmax_2; float Mmax; float m; // === Счётчики цикла / режим (используются часто) === int schetchick = 0; // REORDER: чуть ниже Mmax/m int mcQueenSpeed = 1; // === Горячие локальные переменные цикла, сгруппированы по фазам использования === // 1) Выбор/оценка точки и координаты по Пеано (LNA hotspot) float new_point, new_value; // REORDER: ближе к Shag/RastriginFunc const PeanoCurve_2D* __restrict pc; float new_x1, new_x2; // 2) Работа с кучей интервалов (split/best) std::unique_ptr<Interval> promejutochny_otrezok; std::unique_ptr<Interval> curr; std::unique_ptr<Interval> curr1; float currM; float len2, len1; float len_item; size_t r_size; // 3) Переоценка характеристик / глобальная перенастройка float progress, alpha, betta, MULTIPLIER, global_coeff, GLOBAL_FACTOR; // 4) Доступ к top и критерии (epsilon/длина) const std::unique_ptr<Interval>* __restrict top_ptr; float interval_len; // 5) Коммуникации (MPI hotspot), сгруппированы отдельно boost::optional<boost::mpi::status> probe_status; int dummy; const PeanoCurve_2D* __restrict p1L; const PeanoCurve_2D* __restrict p2L; CrossMsg outbound; CrossMsg inbound; std::unique_ptr<Interval> injected; float newParam1_remote1, newParam2_remote1, newParam1_remote2, newParam2_remote2; // 6) «Охлаждение» и периодика — считаются каждый шаг float cooling, T, k; if (N == 1.0f) { // === Базовая геометрия интервала и пороги === initial_length = b - a; dmax = initial_length; threshold_03 = 0.3f * initial_length; inv_threshold_03 = 1.0f / threshold_03; // === Стартовые оценки функции на краях === start_val = ShekelFunc(a, seed); best_f = ShekelFunc(b, seed); // === «Горячая» четвёрка max-интервала === x_Rmax_1 = a; x_Rmax_2 = b; y_Rmax_1 = start_val; y_Rmax_2 = best_f; // === Контейнеры под результаты и кучу интервалов === Extr.reserve(global_iterations * 4u); // REORDER: выше clear Extr.clear(); R.reserve(global_iterations * 2u); R.clear(); // === Начальный интервал и параметры m/M === R.emplace_back(std::make_unique<Interval>(&a, &b, &start_val, &best_f, &N)); std::push_heap(R.begin(), R.end(), ComparePtr); Mmax = *R.front()->M; m = r * Mmax; while (true) { // ... ТЕЛО ЦИКЛА БЕЗ ИЗМЕНЕНИЙ ... // Используются вынесенные переменные, которые перезаписываются каждую итерацию new_point = Shag(m, x_Rmax_1, x_Rmax_2, y_Rmax_1, y_Rmax_2, N, r); new_value = ShekelFunc(new_point, seed); if (new_value < best_f) { best_f = new_value; Extr.emplace_back(best_f); Extr.emplace_back(new_point); } // Разбиение лучшего интервала std::pop_heap(R.begin(), R.end(), ComparePtr); promejutochny_otrezok = std::move(R.back()); R.pop_back(); // Создаём подынтервалы curr = std::make_unique<Interval>(promejutochny_otrezok->x1, &new_point, promejutochny_otrezok->y1, &new_value, &N); curr1 = std::make_unique<Interval>(&new_point, promejutochny_otrezok->x2, &new_value, promejutochny_otrezok->y2, &N); currM = *curr->M > *curr1->M ? *curr->M : *curr1->M; len2 = *promejutochny_otrezok->x2 - new_point; len1 = new_point - *promejutochny_otrezok->x1; interval_len = len1 < len2 ? len1 : len2; if (++schetchick == global_iterations || interval_len < epsilon) { if (g_world->rank() == 0) { Extr.emplace_back(schetchick); Extr.emplace_back(interval_len); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } if (len2 + len1 == dmax) { dmax = len2 > len1 ? len2 : len1; size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
len_item = *R[i]->x2 - *R[i]->x1;
if (len_item > dmax) {
dmax = len_item;
}
++i;
}
}
textif (mode) { if (threshold_03 > dmax && fmodf(schetchick, 3.0f) == 0.0f || 10.0f * dmax < initial_length) { if (currM > Mmax) { Mmax = currM; m = r * Mmax; } progress = fmaf(-inv_threshold_03, dmax, 1.0f); alpha = fmaf(progress, progress, 1.0f); betta = 2.0f - alpha; MULTIPLIER = (1.0f / dmax) * Mmax; global_coeff = fmaf(MULTIPLIER, r, -MULTIPLIER); GLOBAL_FACTOR = betta * global_coeff; curr->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len1, *curr->M * alpha)); curr1->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len2, *curr1->M * alpha)); size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, *R[i]->x2 - *R[i]->x1, *R[i]->M * alpha));
++i; // Increment moved inside the loop body
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(m);
++i;
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
}
}
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(m);
++i;
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
}
}
text// Добавляем новые интервалы R.emplace_back(std::move(curr)); std::push_heap(R.begin(), R.end(), ComparePtr); R.emplace_back(std::move(curr1)); std::push_heap(R.begin(), R.end(), ComparePtr); // Обновление x_Rmax и y_Rmax top_ptr = &R.front(); x_Rmax_1 = *(*top_ptr)->x1; x_Rmax_2 = *(*top_ptr)->x2; y_Rmax_1 = *(*top_ptr)->y1; y_Rmax_2 = *(*top_ptr)->y2; } } else { // === Длины/пороги, используемые в каждом обороте === initial_length = true_end - true_start; dmax = initial_length; // REORDER: рядом с initial_length threshold_03 = 0.3f * initial_length; inv_threshold_03 = 1.0f / threshold_03; // === Стартовые значения функции и «горячая» пара y_Rmax/best_f === start_val = rank ? RastriginFunc(true_end, d - y_addition) : RastriginFunc(true_start, c + y_addition); y_Rmax_1 = start_val; // REORDER: сразу за end_val best_f = rank ? RastriginFunc(true_start, d - y_addition) : RastriginFunc(true_end, c + y_addition); y_Rmax_2 = best_f; // REORDER: рядом с best_f // === Резервы под контейнеры (до первого использования) === Extr.reserve(global_iterations * 4u); // REORDER: выше clear Extr.clear(); R.reserve(global_iterations * 2u); R.clear(); // === Начальный интервал и его характеристика (сразу после подготовки контейнеров) === R.emplace_back(std::make_unique<Interval>(&true_start, &true_end, &start_val, &best_f, &N)); Mmax = *R.front()->M; m = r * Mmax; while (true) { // MPI проверки probe_status = g_world->iprobe(partner, boost::mpi::any_tag); if (probe_status->tag() == 0) { g_world->irecv(partner, 0, mcQueenSpeed); } else if (probe_status->tag() == 2) { g_world->irecv(partner, 2, dummy); if (partner) { top_ptr = &R.front(); Extr.emplace_back(schetchick); Extr.emplace_back(*(*top_ptr)->x2 - *(*top_ptr)->x1); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } // Условие завершения по итерациям if (++schetchick == global_iterations) { g_world->isend(partner, 2, 0); if (partner) { top_ptr = &R.front(); Extr.emplace_back(schetchick); Extr.emplace_back(*(*top_ptr)->x2 - *(*top_ptr)->x1); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } // «Охлаждение» и период T cooling = ldexpf(1.0f, -schetchick * (1.0f / 138.63f)); T = floorf(fmaf(20.0f, cooling, 10.0f)); k = fmaf(0.2f, cooling, 0.7f); if (!(fmodf(schetchick, T)) == mcQueenSpeed) { top_ptr = &R.front(); p1L = Curve->HitTest_2D(*(*top_ptr)->x1); p2L = Curve->HitTest_2D(*(*top_ptr)->x2); outbound = CrossMsg{ p1L->x1, p1L->x2, p2L->x1, p2L->x2, *(*top_ptr)->R }; if (mcQueenSpeed) { g_world->isend(partner, 0, 0); } else { mcQueenSpeed = 1; } g_world->isend(partner, 1, outbound); g_world->irecv(partner, 1, inbound); // Проекция удалённых точек newParam1_remote1 = Curve->FindX_2D(inbound.s_x1, inbound.s_x2); newParam2_remote1 = Curve->FindX_2D(inbound.e_x1, inbound.e_x2); newParam1_remote2 = RastriginFunc(inbound.s_x1, inbound.s_x2); newParam2_remote2 = RastriginFunc(inbound.e_x1, inbound.e_x2); // «Инъекция» с пониженной характеристикой injected = std::make_unique<Interval>(&newParam1_remote1, &newParam2_remote1, &newParam1_remote2, &newParam2_remote2, &N); *injected->R = inbound.Rtop * k; R.emplace_back(std::move(injected)); std::push_heap(R.begin(), R.end(), ComparePtr); } // Локальный шаг LNA new_point = Shag(m, x_Rmax_1, x_Rmax_2, y_Rmax_1, y_Rmax_2, N, r); // Координаты по кривой Пеано pc = Curve->HitTest_2D(new_point); new_x1 = pc->x1; new_x2 = pc->x2; new_value = RastriginFunc(new_x1, new_x2); // Обновление экстремумов if (new_value < best_f) { best_f = new_value; Extr.emplace_back(best_f); Extr.emplace_back(new_x1); Extr.emplace_back(new_x2); } // Разбиение лучшего интервала std::pop_heap(R.begin(), R.end(), ComparePtr); promejutochny_otrezok = std::move(R.back()); R.pop_back(); // Создаём подынтервалы curr = std::make_unique<Interval>(promejutochny_otrezok->x1, &new_point, promejutochny_otrezok->y1, &new_value, &N); curr1 = std::make_unique<Interval>(&new_point, promejutochny_otrezok->x2, &new_value, promejutochny_otrezok->y2, &N); currM = *curr->M > *curr1->M ? *curr->M : *curr1->M; len2 = *promejutochny_otrezok->x2 - new_point; len1 = new_point - *promejutochny_otrezok->x1; r_size = R.size(); if (len2 + len1 == dmax) { dmax = len2 > len1 ? len2 : len1; size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
len_item = *R[i]->x2 - *R[i]->x1;
if (len_item > dmax) {
dmax = len_item;
}
++i;
}
}
textif (mode) { if (threshold_03 > dmax && fmodf(schetchick, 3.0f) == 0.0f || 10.0f * dmax < initial_length) { if (currM > Mmax) { Mmax = currM; m = r * Mmax; } progress = fmaf(-inv_threshold_03, dmax, 1.0f); alpha = fmaf(progress, progress, 1.0f); betta = 2.0f - alpha; MULTIPLIER = (1.0f / dmax) * Mmax; global_coeff = fmaf(MULTIPLIER, r, -MULTIPLIER); GLOBAL_FACTOR = betta * global_coeff; curr->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len1, *curr->M * alpha)); curr1->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, len2, *curr1->M * alpha)); size_t i = 0u; // Initialization moved before the loop
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, *R[i]->x2 - *R[i]->x1, *R[i]->M * alpha));
++i; // Increment moved inside the loop body
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(m);
++i;
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
}
}
}
else {
if (currM > Mmax) {
Mmax = currM;
m = r * Mmax;
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
size_t i = 0u;
#pragma loop(ivdep)
while (i < r_size) {
R[i]->ChangeCharacteristic(m);
++i;
}
std::make_heap(R.begin(), R.end(), ComparePtr);
}
else {
curr->ChangeCharacteristic(m);
curr1->ChangeCharacteristic(m);
}
}
text// Добавление подынтервалов R.emplace_back(std::move(curr)); std::push_heap(R.begin(), R.end(), ComparePtr); R.emplace_back(std::move(curr1)); std::push_heap(R.begin(), R.end(), ComparePtr); // Проверка критерия сходимости top_ptr = &R.front(); interval_len = *(*top_ptr)->x2 - *(*top_ptr)->x1; if (interval_len < epsilon) { g_world->isend(partner, 2, 0); if (partner) { Extr.emplace_back(schetchick); Extr.emplace_back(interval_len); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } // Обновляем x_Rmax и y_Rmax x_Rmax_1 = *(*top_ptr)->x1; x_Rmax_2 = *(*top_ptr)->x2; y_Rmax_1 = *(*top_ptr)->y1; y_Rmax_2 = *(*top_ptr)->y2; } }
} мне верни рабочую версию кода с вынесенными переменными как например в моём втором примере правда он запускается с ошибкой - так что сделай как мой второй пример но гарантировано рабочую версию и оптимальным размещением общих переменных для лучшей локальности данных размещения их в кеше минимизации кеш промахов и оптимальной производительности по скорости
ниже — рабочая версия с «вынесенными» общими переменными, но без ловушек из вашего второго варианта (главные фиксы: не трогаем Curve
/развёртку в 1D-ветке, корректно инициализируем r_size
в 1D, и аккуратно работаем с iprobe
через проверку optional
). Переменные объявлены единообразно «сверху», а вычисляются там, где это безопасно (для кэша и без ложных зависимостей).
cppextern "C" __declspec(dllexport) __declspec(noalias) void Base_LNA_1_2_Mer_AGP( const float N, const float global_iterations, const float a, const float b, const float c, const float d, const float r, const bool mode, const float epsilon, const float seed, float** __restrict out_data, size_t* __restrict out_len) noexcept { // === Общая топология процесса === const int rank = g_world->rank(); const int partner = rank ^ 1; // === Геометрия развёртки (объявления общие, но вычисляем ТОЛЬКО в 2D) === float divider = 0.0f; float inv_divider = 0.0f; float x_addition = 0.0f; float y_addition = 0.0f; float true_start = 0.0f; float true_end = 0.0f; // === «Горячая» пара X-границ текущего max-интервала (для Shag) === float x_Rmax_1 = 0.0f; float x_Rmax_2 = 0.0f; // === Длины/пороги === float initial_length = 0.0f; float dmax = 0.0f; float threshold_03 = 0.0f; float inv_threshold_03 = 0.0f; // === Значения функции и best === float start_val = 0.0f; float best_f = 0.0f; float y_Rmax_1 = 0.0f; float y_Rmax_2 = 0.0f; // === Характеристика === float Mmax = 0.0f; float m = 0.0f; // === Счётчики / периодика === int schetchick = 0; int mcQueenSpeed = 1; // === Временные переменные ядра цикла === // 1) Выбор/оценка точки float new_point = 0.0f, new_value = 0.0f; const PeanoCurve_2D* __restrict pc = nullptr; // используется только в 2D float new_x1 = 0.0f, new_x2 = 0.0f; // 2) Работа с кучей интервалов std::unique_ptr<Interval> promejutochny_otrezok; std::unique_ptr<Interval> curr; std::unique_ptr<Interval> curr1; float currM = 0.0f; float len1 = 0.0f; float len2 = 0.0f; float len_item = 0.0f; size_t r_size = 0; // 3) Переоценка характеристик float progress = 0.0f, alpha = 0.0f, betta = 0.0f; float MULTIPLIER = 0.0f, global_coeff = 0.0f, GLOBAL_FACTOR = 0.0f; // 4) Доступ к top и критерии const std::unique_ptr<Interval>* __restrict top_ptr = nullptr; float interval_len = 0.0f; // 5) Коммуникации (только 2D) boost::optional<boost::mpi::status> probe_status; int dummy = 0; const PeanoCurve_2D* __restrict p1L = nullptr; const PeanoCurve_2D* __restrict p2L = nullptr; CrossMsg outbound{}; CrossMsg inbound{}; std::unique_ptr<Interval> injected; float newParam1_remote1 = 0.0f, newParam2_remote1 = 0.0f; float newParam1_remote2 = 0.0f, newParam2_remote2 = 0.0f; // 6) «Охлаждение» (только 2D) float cooling = 0.0f, T = 0.0f, k = 0.0f; if (N == 1.0f) { // === 1D: НИКАКИХ обращений к Curve === initial_length = b - a; dmax = initial_length; threshold_03 = 0.3f * initial_length; inv_threshold_03 = 1.0f / threshold_03; start_val = ShekelFunc(a, seed); best_f = ShekelFunc(b, seed); x_Rmax_1 = a; x_Rmax_2 = b; y_Rmax_1 = start_val; y_Rmax_2 = best_f; Extr.reserve(static_cast<size_t>(global_iterations) * 4u); Extr.clear(); R.reserve(static_cast<size_t>(global_iterations) * 2u); R.clear(); R.emplace_back(std::make_unique<Interval>(&a, &b, &start_val, &best_f, &N)); std::push_heap(R.begin(), R.end(), ComparePtr); Mmax = *R.front()->M; m = r * Mmax; // Локальные буферы для безопасной передачи значений в Interval (как в исходнике) float x1 = 0.0f, y1 = 0.0f, x2 = 0.0f, y2 = 0.0f; while (true) { // Шаг LNA new_point = Shag(m, x_Rmax_1, x_Rmax_2, y_Rmax_1, y_Rmax_2, N, r); new_value = ShekelFunc(new_point, seed); if (new_value < best_f) { best_f = new_value; Extr.emplace_back(best_f); Extr.emplace_back(new_point); } // Разбиение лучшего интервала std::pop_heap(R.begin(), R.end(), ComparePtr); promejutochny_otrezok = std::move(R.back()); R.pop_back(); // Берём значения в локальные буферы (ВАЖНО: как в 1D-оригинале) x1 = *promejutochny_otrezok->x1; y1 = *promejutochny_otrezok->y1; x2 = *promejutochny_otrezok->x2; y2 = *promejutochny_otrezok->y2; len2 = x2 - new_point; len1 = new_point - x1; interval_len = (len1 < len2) ? len1 : len2; // Лимиты/сходимость if (++schetchick == static_cast<int>(global_iterations) || interval_len < epsilon) { if (rank == 0) { Extr.emplace_back(static_cast<float>(schetchick)); Extr.emplace_back(interval_len); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } // Создаём подынтервалы (с передачей адресов локальных буферов — как в старом коде) curr = std::make_unique<Interval>(&x1, &new_point, &y1, &new_value, &N); curr1 = std::make_unique<Interval>(&new_point, &x2, &new_value, &y2, &N); currM = (*curr->M > *curr1->M) ? *curr->M : *curr1->M; r_size = R.size(); if ((len2 + len1) == dmax) { dmax = (len2 > len1) ? len2 : len1; size_t i = 0u; #pragma loop(ivdep) while (i < r_size) { len_item = *R[i]->x2 - *R[i]->x1; if (len_item > dmax) dmax = len_item; ++i; } } if (mode) { if ((threshold_03 > dmax && fmodf(static_cast<float>(schetchick), 3.0f) == 0.0f) || 10.0f * dmax < initial_length) { if (currM > Mmax) { Mmax = currM; m = r * Mmax; } progress = fmaf(-inv_threshold_03, dmax, 1.0f); alpha = fmaf(progress, progress, 1.0f); betta = 2.0f - alpha; MULTIPLIER = (1.0f / dmax) * Mmax; global_coeff = fmaf(MULTIPLIER, r, -MULTIPLIER); GLOBAL_FACTOR= betta * global_coeff; curr->ChangeCharacteristic( fmaf(GLOBAL_FACTOR, len1, *curr->M * alpha)); curr1->ChangeCharacteristic( fmaf(GLOBAL_FACTOR, len2, *curr1->M * alpha)); size_t i = 0u; #pragma loop(ivdep) while (i < r_size) { R[i]->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, *R[i]->x2 - *R[i]->x1, *R[i]->M * alpha)); ++i; } std::make_heap(R.begin(), R.end(), ComparePtr); } else { if (currM > Mmax) { Mmax = currM; m = r * Mmax; curr->ChangeCharacteristic(m); curr1->ChangeCharacteristic(m); size_t i = 0u; #pragma loop(ivdep) while (i < r_size) { R[i]->ChangeCharacteristic(m); ++i; } std::make_heap(R.begin(), R.end(), ComparePtr); } else { curr->ChangeCharacteristic(m); curr1->ChangeCharacteristic(m); } } } else { if (currM > Mmax) { Mmax = currM; m = r * Mmax; curr->ChangeCharacteristic(m); curr1->ChangeCharacteristic(m); size_t i = 0u; #pragma loop(ivdep) while (i < r_size) { R[i]->ChangeCharacteristic(m); ++i; } std::make_heap(R.begin(), R.end(), ComparePtr); } else { curr->ChangeCharacteristic(m); curr1->ChangeCharacteristic(m); } } // Добавляем подынтервалы R.emplace_back(std::move(curr)); std::push_heap(R.begin(), R.end(), ComparePtr); R.emplace_back(std::move(curr1)); std::push_heap(R.begin(), R.end(), ComparePtr); // Обновляем «горячую» пару top_ptr = &R.front(); x_Rmax_1 = *(*top_ptr)->x1; x_Rmax_2 = *(*top_ptr)->x2; y_Rmax_1 = *(*top_ptr)->y1; y_Rmax_2 = *(*top_ptr)->y2; } } else { // === 2D: развёртка по Пеано — вычисляем только здесь === divider = ldexpf(1.0f, (Curve->razvertka << 1) + 1); inv_divider = 1.0f / divider; x_addition = (b - a) * inv_divider; y_addition = (d - c) * inv_divider; true_start = a + x_addition; true_end = b - x_addition; x_Rmax_1 = true_start; x_Rmax_2 = true_end; initial_length = true_end - true_start; dmax = initial_length; threshold_03 = 0.3f * initial_length; inv_threshold_03 = 1.0f / threshold_03; start_val = rank ? RastriginFunc(true_end, d - y_addition) : RastriginFunc(true_start, c + y_addition); y_Rmax_1 = start_val; best_f = rank ? RastriginFunc(true_start, d - y_addition) : RastriginFunc(true_end, c + y_addition); y_Rmax_2 = best_f; Extr.reserve(static_cast<size_t>(global_iterations) * 4u); Extr.clear(); R.reserve(static_cast<size_t>(global_iterations) * 2u); R.clear(); R.emplace_back(std::make_unique<Interval>(&true_start, &true_end, &start_val, &best_f, &N)); Mmax = *R.front()->M; m = r * Mmax; while (true) { // MPI: опрос только если есть сообщение probe_status = g_world->iprobe(partner, boost::mpi::any_tag); if (probe_status) { const int tag = probe_status->tag(); if (tag == 0) { g_world->irecv(partner, 0, mcQueenSpeed); } else if (tag == 2) { g_world->irecv(partner, 2, dummy); if (partner) { top_ptr = &R.front(); Extr.emplace_back(static_cast<float>(schetchick)); Extr.emplace_back(*(*top_ptr)->x2 - *(*top_ptr)->x1); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } } // Лимит по итерациям if (++schetchick == static_cast<int>(global_iterations)) { g_world->isend(partner, 2, 0); if (partner) { top_ptr = &R.front(); Extr.emplace_back(static_cast<float>(schetchick)); Extr.emplace_back(*(*top_ptr)->x2 - *(*top_ptr)->x1); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } // «Охлаждение» и периодика cooling = ldexpf(1.0f, -schetchick * (1.0f / 138.63f)); T = floorf(fmaf(20.0f, cooling, 10.0f)); k = fmaf(0.2f, cooling, 0.7f); if (!(fmodf(static_cast<float>(schetchick), T)) == mcQueenSpeed) { top_ptr = &R.front(); p1L = Curve->HitTest_2D(*(*top_ptr)->x1); p2L = Curve->HitTest_2D(*(*top_ptr)->x2); outbound = CrossMsg{ p1L->x1, p1L->x2, p2L->x1, p2L->x2, *(*top_ptr)->R }; if (mcQueenSpeed) { g_world->isend(partner, 0, 0); } else { mcQueenSpeed = 1; } g_world->isend(partner, 1, outbound); g_world->irecv(partner, 1, inbound); // Проекция удалённых точек newParam1_remote1 = Curve->FindX_2D(inbound.s_x1, inbound.s_x2); newParam2_remote1 = Curve->FindX_2D(inbound.e_x1, inbound.e_x2); newParam1_remote2 = RastriginFunc(inbound.s_x1, inbound.s_x2); newParam2_remote2 = RastriginFunc(inbound.e_x1, inbound.e_x2); // Инъекция injected = std::make_unique<Interval>(&newParam1_remote1, &newParam2_remote1, &newParam1_remote2, &newParam2_remote2, &N); *injected->R = inbound.Rtop * k; R.emplace_back(std::move(injected)); std::push_heap(R.begin(), R.end(), ComparePtr); } // Локальный шаг new_point = Shag(m, x_Rmax_1, x_Rmax_2, y_Rmax_1, y_Rmax_2, N, r); // Координаты по кривой Пеано pc = Curve->HitTest_2D(new_point); new_x1 = pc->x1; new_x2 = pc->x2; new_value = RastriginFunc(new_x1, new_x2); if (new_value < best_f) { best_f = new_value; Extr.emplace_back(best_f); Extr.emplace_back(new_x1); Extr.emplace_back(new_x2); } // Разбиение std::pop_heap(R.begin(), R.end(), ComparePtr); promejutochny_otrezok = std::move(R.back()); R.pop_back(); // Подынтервалы (как в 2D-оригинале — с передачей указателей из исходного интервала) curr = std::make_unique<Interval>(promejutochny_otrezok->x1, &new_point, promejutochny_otrezok->y1, &new_value, &N); curr1 = std::make_unique<Interval>(&new_point, promejutochny_otrezok->x2, &new_value, promejutochny_otrezok->y2, &N); currM = (*curr->M > *curr1->M) ? *curr->M : *curr1->M; len2 = *promejutochny_otrezok->x2 - new_point; len1 = new_point - *promejutochny_otrezok->x1; r_size = R.size(); if ((len2 + len1) == dmax) { dmax = (len2 > len1) ? len2 : len1; size_t i = 0u; #pragma loop(ivdep) while (i < r_size) { len_item = *R[i]->x2 - *R[i]->x1; if (len_item > dmax) dmax = len_item; ++i; } } if (mode) { if ((threshold_03 > dmax && fmodf(static_cast<float>(schetchick), 3.0f) == 0.0f) || 10.0f * dmax < initial_length) { if (currM > Mmax) { Mmax = currM; m = r * Mmax; } progress = fmaf(-inv_threshold_03, dmax, 1.0f); alpha = fmaf(progress, progress, 1.0f); betta = 2.0f - alpha; MULTIPLIER = (1.0f / dmax) * Mmax; global_coeff = fmaf(MULTIPLIER, r, -MULTIPLIER); GLOBAL_FACTOR= betta * global_coeff; curr->ChangeCharacteristic( fmaf(GLOBAL_FACTOR, len1, *curr->M * alpha)); curr1->ChangeCharacteristic( fmaf(GLOBAL_FACTOR, len2, *curr1->M * alpha)); size_t i = 0u; #pragma loop(ivdep) while (i < r_size) { R[i]->ChangeCharacteristic(fmaf(GLOBAL_FACTOR, *R[i]->x2 - *R[i]->x1, *R[i]->M * alpha)); ++i; } std::make_heap(R.begin(), R.end(), ComparePtr); } else { if (currM > Mmax) { Mmax = currM; m = r * Mmax; curr->ChangeCharacteristic(m); curr1->ChangeCharacteristic(m); size_t i = 0u; #pragma loop(ivdep) while (i < r_size) { R[i]->ChangeCharacteristic(m); ++i; } std::make_heap(R.begin(), R.end(), ComparePtr); } else { curr->ChangeCharacteristic(m); curr1->ChangeCharacteristic(m); } } } else { if (currM > Mmax) { Mmax = currM; m = r * Mmax; curr->ChangeCharacteristic(m); curr1->ChangeCharacteristic(m); size_t i = 0u; #pragma loop(ivdep) while (i < r_size) { R[i]->ChangeCharacteristic(m); ++i; } std::make_heap(R.begin(), R.end(), ComparePtr); } else { curr->ChangeCharacteristic(m); curr1->ChangeCharacteristic(m); } } // Добавление подынтервалов R.emplace_back(std::move(curr)); std::push_heap(R.begin(), R.end(), ComparePtr); R.emplace_back(std::move(curr1)); std::push_heap(R.begin(), R.end(), ComparePtr); // Критерий сходимости top_ptr = &R.front(); interval_len= *(*top_ptr)->x2 - *(*top_ptr)->x1; if (interval_len < epsilon) { g_world->isend(partner, 2, 0); if (partner) { Extr.emplace_back(static_cast<float>(schetchick)); Extr.emplace_back(interval_len); *out_len = Extr.size(); *out_data = reinterpret_cast<float*>(CoTaskMemAlloc(sizeof(float) * (*out_len))); memcpy(*out_data, Extr.data(), sizeof(float) * (*out_len)); } return; } // Обновление «горячей» пары x_Rmax_1 = *(*top_ptr)->x1; x_Rmax_2 = *(*top_ptr)->x2; y_Rmax_1 = *(*top_ptr)->y1; y_Rmax_2 = *(*top_ptr)->y2; } } }
Что изменено/почему это стабильно и быстро:
Curve
(развёртка/Peano-границы) не вычисляются в 1D — это устраняет падение из вашего примера.r_size
перед векторными проходами и сохранён исходный «буферный» стиль (x1/y1/x2/y2
как локальные «контейнеры»), чтобы не менять семантику Interval
.iprobe
проверяется на наличие статуса перед обращением к tag()
— без этого возможен UB/крэш.x_Rmax_*
, y_Rmax_*
), держим рядом в памяти — это даёт лучшую предсказуемость для L1/L2.Если хотите, могу показать diff к вашему второму варианту, чтобы наглядно увидеть только нужные правки.