Может ли кто-нибудь обновить это до современного C++, чтобы я мог лучше понять, что происходит?
https://stackoverflow.com/a/21642962/10470367
Я пытался заменить указатель на points на std::vector, чтобы устранить необходимость ручного выделения памяти.
Я также пытался использовать for (auto& foo : foos), но я просто не могу следовать логике этой математики.
Кроме того, я понимаю, что это улучшит его оптимизацию за счет обновления до современного C++.
@ Стив, я понимаю твою точку зрения. Я не думаю, что это не по теме, но я согласен с тем, что, по крайней мере, текущий пример наилучшего усилия был бы хорош. Я думаю, что мы увидим больше этих вопросов по мере развития C++ 17 (а вскоре и C++ 20).
@JonHarper: Связанный код не просто плох по стандартам C++ 17. Это даже не хороший код на C++ 98.





point getBezierPoint( span<const point> points, float t ) {
vector<point> tmp = as_vector(points);
while (tmp.size()>1) {
for (auto k:indexes_of(tmp).except_last())
tmp[k] = tmp[k] + t * ( tmp[k+1] - tmp[k] );
tmp.resize(tmp.size()-1);
}
return tmp[0];
}
span, as_vector и point должны быть очевидны.
Вот indexes_of:
template<class It>
struct range_t{
It b,e;
It begin()const{return b;}
It end()const{return e;}
range_t except_last(std::size_t i=1)const{
auto r = *this;
r.e-=i;
return r;
}
};
template<class It>
range_t<It> range(It be, It e){ return {std::move(b),std::move(e)}; }
template<class X>
struct indexer_t {
X x;
X operator*()const{return x;}
void operator++(){ ++x; }
void operator--(){ --x; }
void operator+=(std::ptrdiff_t i){ x+=i; }
void operator-=(std::ptrdiff_t i){ x-=i; }
friend bool operator==(indexer_t const&lhs, indexer_t const& rhs){return lhs.x==rhs.x;}
friend bool operator!=(indexer_t const&lhs, indexer_t const& rhs){return lhs.x!=rhs.x;}
};
range_t<indexer_t<std::size_t>> count( std::size_t start, std::size_t finish ){
return {{start}, {finish}};
}
template<class C>
auto indexes_of(C&&c) { return count(0, c.size()); }
или что-то в этом роде.
Хотя это работает, это несколько неэффективно. Он повторно генерирует indexes_of(tmp). Этот стиль также затрудняет оптимизатору создание кода SIMD (например, AVX или NEON).
@msal индексы tmp - это числа 0 и размер-1. Всего 2 числа.
Конечно, но size продолжает меняться из-за того, что .resize во внешнем цикле.
«Кроме того, я понимаю, что это улучшит его оптимизацию за счет обновления до современного C++»
На самом деле код выглядит так, будто лучшая оптимизация - это векторизация, например используя AVX на x86 или NEON на ARM. И это лучше всего работает, если векторизатор может работать с индексами и четкими границами. Так:
vec2 getBezierPoint( std::vector<vec2> points, float t ) {
auto const maxi = points.size()-1;
for(int i = 0; i != maxi; ++i)
{
auto const maxj = maxi-i;
for (int j = 0; j < maxj; ++j)
points[j] += t * ( points[j+1] - points[j] );
}
return points[0];
}
Однако обратите внимание, что основная проблема оптимизации заключается в том, что вы получаете только одно очко за раз. Обычно вам нужна вся кривая (от t = 0,0 до t = 1,0), а затем выполняется довольно много избыточной работы - все эти границы цикла идентичны для всех значений t.
Странный вопрос. Я бы оставил ссылку на исходный вопрос, но разместите здесь код с конкретным запросом о том, с чем у вас проблемы. Это почти похоже на вопрос типа «мой код не работает, что не так? <Код>» (который не по теме), но я знаю, что это не так. Если бы это была ссылка на код сайта, не относящегося к StackExchange, она была бы отклонена и, возможно, закрыта.