2009-05-07 6 views
21

У меня есть общее представление о restrict, но я надеюсь уточнить некоторые моменты. У меня есть функция, которая считывает строку с нулевым завершением из одного буфера и выписывает версию с кодировкой URL в другом буфере. Функция имеет эту подпись (без restrict):Когда использовать ограничение и когда не

char const *StringUrlEncode(char const *unencoded, 
          char *encoded, 
          char *encodedEnd); 

unencoded мой завершающим нулем исходной строки. Буфер назначения представлен encoded и encodedEnd, где encoded указывает на первый char в буфере и encodedEnd указывает на первый символ после буфера т.е. функция будет писать char s до, но не включая место указал до encodedEnd - это ваша основная пара итераторов begin/end, если вы знакомы с соглашениями STL на языке C++.

Если добавить restrict к этой функции, она должна применяться только к первым двум параметрам:

char const *StringUrlEncode(char const *restrict unencoded, 
          char *restrict encoded, 
          char *encodedEnd); 

или есть какая-то польза, я не понимая, добавляя его по всем трем параметрам?

Я вижу, что создание входных и выходных буферов restrict помогает компилятору понять, что они не перекрываются. Но поскольку последний параметр, encodedEnd, используется только для обозначения конца выходного буфера, я думаю, что restrict на самом деле не будет никакой помощью для компилятора здесь (хотя я предполагаю, что это не повредит, кроме добавления ненужный шум для объявления функции).

ответ

12

Попробуйте статью Майка Актона here. Ограничение пугает из-за как последствий, связанных с использованием, так и последствий неправильного использования.

В вашем случае это звучит так, как будто вы можете безопасно применять ограничения для всех трех указателей, так как ни одна из них не имеет одинаковой области памяти. Однако от использования его на третьем указателе будет мало пользы от производительности.

+1

Я прочитал статью Майка (дважды сейчас), и это хорошее начало, но оставил мне несколько вопросов :-) –

+1

Указанная ссылка нефункциональна. Google предлагает обновленную версию по адресу http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html (проверено 2009-09-06), но это также создает проблемы. Кэшированная версия доступна в Google. –

4

Я думаю, вы правы, что это не повредит. Ваш указатель цикла (назовите его p) будет равен encodedEnd в конце цикла. Но ничто не должно быть доступно после цикла (из p или encodedEnd), поэтому это не должно быть проблемой. Я не думаю, что это тоже поможет, потому что ничего не написано или не прочитано из encodedEnd, поэтому нет ничего, что могло бы оптимизировать.

Но я согласен с тобой, что первые два ограничения должны действительно помочь.

+0

Обратите внимание, что разыменование закодированоEnd является неопределенным поведением, поскольку кодировка также ограничена - так что действительно не имеет значения, ограничено ли encodedEnd или нет. – bdonlan

7

В данном конкретном случае не имеет значения, является ли ограничение encodedEnd; вы пообещали компилятору, что никто не псевдонизирует некодированный и закодирован, и поэтому чтения и записи не будут мешать друг другу.

Реальная причина того, что ограничение важно в данном случае является то, что без него компилятор не может знать, что пишет через кодируются не будет влиять на прочитывает незакодированной.Например, если

encoded == unencoded+1 

затем каждая запись в кодируемого затронет каждое последующее чтение из незакодированной, поэтому компилятор не может планировать нагрузку до тех пор, пока запись завершена. ограничить обещание компилятора о том, что два указателя не влияют на одну и ту же память, поэтому он может планировать нагрузки достаточно далеко вперед, чтобы избежать простоя трубопроводов.

 Смежные вопросы

  • Нет связанных вопросов^_^