Просто интересно, подтвердит ли кто-нибудь несколько правил псевдонимов для меня.
Я знаю, что сглаживание (например, проблемы с загрузкой) может привести к тому, что следующий тип кода будет субоптимальным, потому что мы не можем предположить, что x, y, z
не перекрываются:
// case 1:
void plus(size_t n, double *x, double *y, double *z)
{
for (size_t i = 0; i != n; ++i)
z[i] = x[i] + y[i];
}
Я знаю, что есть ключевое слово C __restrict
, которое подсказывает компилятору, что он не должен рассматривать перекрывающийся случай и, следовательно, потенциально генерировать лучший код:
// case 2:
void plus(size_t n, double *__restrict x, double *__restrict y, double *__restrict z)
{ // as above... }
Но как сглаживание работает с кодом стиля С++, где мы будем иметь дело с контейнерными объектами, переданными по ссылке, а не с примерами, подобными C, с исходными указателями?
Например, я предполагаю, что будут проблемы с псевдонимом, если мы сделаем следующее:
// case 3:
void plus(std::vector<double> &x, std::vector<double> &y, std::vector<double> &z)
{ // similar to above... }
И чтобы перейти к менее тривиальному примеру, не имеет значения, существуют ли разные типы данных в контейнерах? На уровне реализации большинство контейнеров динамически управляют хранилищем с помощью указателей, поэтому мне не ясно, как компилятор может гарантировать, что следующее не является псевдонимом:
// case 4:
void foo(std::vector<mytype1> &x, std::vector<mytype2> &y)
{ // interwoven operations on x, y... }
Я не пытаюсь оптимизировать микро-оптимизацию, но мне интересно, лучше ли в настоящее время передавать ограниченные указатели на контейнеры, а не ссылки.
EDIT: Чтобы прояснить некоторые термины, как указано: restrict
- это ключевое слово C99. Там также __restrict
и __restrict__
в разных компиляторах, но все они делают то же самое.