es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

std::accumulate vs for loop, aplicación de raytracing

Esta pregunta se basa en este video en YouTube realizado con el propósito de revisar este proyecto.

En el video, el presentador está analizando el proyecto y descubrió que el siguiente bloque de código es la causa de problemas de rendimiento:

“`c++
std::optional<HitRecord> HittableObjectList::Hit(const Ray &r, float t<em>min, float t</em>max) const {
float closest<em>so</em>far = t_max;

<pre><code>return std::accumulate(begin(objects), end(objects), std::optional<HitRecord>{},
[&](const auto &temp_value, const auto &object) {
if(auto temp_hit = object -> Hit(r, t_min, closest_so_far); temp_hit) {
closest_so_far = temp_hit.value().t;
return temp_hit;
}

<pre><code> return temp_value;
</code></pre>

});

<pre><code><br />Yo asumiría que la función <code>std::accumulate</code> funcionaría de manera similar a un bucle <code>for</code>. Descontento con el impacto en el rendimiento allí (y porque, por alguna razón, el perfilador no perfilaba el código lambda [¿una limitación, tal vez?]), el revisor cambió el código a esto:

“`c++
std::optional<HitRecord> HittableObjectList::Hit(const Ray &r, float t<em>min, float t</em>max) const {
float closest<em>so</em>far = t_max;
std::optional<HitRecord> record{};

<pre><code>for(size_t i = 0; i < objects.size(); i++) {
const std::shared_ptr<HittableObject> &object = objects[i];

if(auto temp_hit = object -> Hit(r, t_min, closest_so_far); temp_hit) {
closest_so_far = temp_hit.value().t;
record = temp_hit;
}
}

return record;

Con este cambio, el tiempo de finalización pasó de 7 minutos y 30 segundos a 22 segundos.

Mis preguntas son:
– ¿Ambos bloques de código son idénticos? ¿Por qué std::accumulate tiene una penalización tan enorme aquí?
– ¿Sería mejor el rendimiento si en lugar de usar auto, se usara el tipo explícito?

El revisor mencionó sugerencias como evitar el uso de std::optional y std:shared_ptr aquí debido a la cantidad de llamadas realizadas y ejecutar este código en la GPU en su lugar, pero por ahora solo estoy interesado en los puntos mencionados anteriormente.

Tags:  , ,

Answer

  1. Avatar for davy.ai
    1. A pesar de que ambos bloques de código logran la misma funcionalidad, la implementación subyacente de std::accumulate parece incurrir en una penalidad significativa de rendimiento en este caso. Es posible que esto se deba a los gastos adicionales introducidos por la función lambda utilizada en std::accumulate, así como a la necesidad de construir objetos std::optional<hitrecord> en cada iteración.

    2. El uso de tipos explícitos en lugar de auto no necesariamente mejora el rendimiento, ya que el compilador generalmente es capaz de deducir el tipo correcto en tiempo de compilación. Sin embargo, puede mejorar la legibilidad del código y facilitar la comprensión de los tipos de datos subyacentes involucrados.

Comments are closed.