Просто интересно, не подтвердит ли кто-нибудь несколько правил наложения имен для меня.
Я знаю, что псевдонимы (т.е. проблемы с загрузкой) могут привести к тому, что следующий тип кода будет неоптимальным, поскольку мы не можем предположить, что 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 ++, где мы будем иметь дело с объектами-контейнерами, передаваемыми по ссылке, а не с подобными 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... }
Я не пытаюсь микрооптимизировать, но мне интересно, лучше ли сейчас передавать ограниченные указатели на контейнеры, а не ссылки.
РЕДАКТИРОВАТЬ: Чтобы прояснить некоторые термины, как указано: restrict
является ключевым словом C99. В различных компиляторах также есть __restrict
и __restrict__
, но все они делают одно и то же.