Pregunta

Tengo una comprensión general de restringir pero espero aclarar algunos puntos finos. Tengo una función que lee una cadena terminada en nulo de un búfer y escribe una versión codificada de URL en otro búfer. La función tiene esta firma (actualmente sin restrict ):

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

sin codificar es mi cadena fuente terminada en nulo. El búfer de destino está representado por codificado y encodedEnd , donde codificado apunta al primer char en el búfer y < code> encodedEnd apunta al primer char después de el búfer, es decir, la función escribirá char s hasta pero no incluye el ubicación señalada por encodedEnd : este es su par de iterador begin / end básico si está familiarizado con las convenciones STL de C ++.

Si agrego restrict a esta función, solo debería aplicarse a los dos primeros parámetros:

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

¿o hay algún beneficio que no entiendo al agregarlo a los tres parámetros?

Puedo ver que hacer que los buffers de entrada y salida restrict ayuden al compilador a saber que no se superponen. Pero como el último parámetro, encodedEnd , solo se usa para marcar el final del búfer de salida, creo que restrict realmente no sería de ninguna ayuda para el compilador aquí (aunque supongo que no dolería, aparte de agregar ruido innecesario a la declaración de función).

¿Fue útil?

Solución

Pruebe el artículo de Mike Acton aquí . Restringir es aterrador debido tanto a las implicaciones de rendimiento de no usarlo como a las consecuencias de usarlo incorrectamente.

En su caso, parece que podría aplicar de forma segura la restricción a los tres punteros ya que ninguno alias la misma área de memoria. Sin embargo, habrá poco o ningún beneficio de rendimiento al usarlo en el tercer puntero.

Otros consejos

En este caso particular, no habrá diferencia si encodedEnd es restringido o no; le prometió al compilador que nadie alias sin codificar y codificado , por lo que las lecturas y escrituras no interferirán entre sí.

La verdadera razón por la que restringir es importante en este caso es que sin él el compilador no puede saber que las escrituras a través de codificadas no afectarán las lecturas a través de no codificadas . Por ejemplo, si

encoded == unencoded+1

entonces cada escritura en codificada afectaría cada lectura posterior de sin codificar , por lo que el compilador no puede programar la carga hasta que la escritura se haya completado. Restringir promete al compilador que los dos punteros no afectan la misma memoria, por lo que puede programar cargas con suficiente antelación para evitar bloqueos de canalización.

Creo que tienes razón en que no dolería. Su puntero de bucle (llámelo p) será igual codificado Fin al final del bucle. Pero no es necesario acceder a nada después del bucle (desde p o codifiedEnd), por lo que no debería ser un problema. Tampoco creo que ayude, porque nunca se escribe o lee nada desde el final codificado, por lo que no hay nada que optimizar.

Pero estoy de acuerdo con que tener las dos primeras restricciones realmente debería ayudar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top