2013-11-29 3 views
1

У меня есть два метода, используемых для рендеринга сетки. Первый из них:улучшение скорости выполнения этой части кода

void Grid::openglRender(){ 
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
    glBegin(GL_TRIANGLES); 
    glColor3f(1.0f, 1.0f, 0.0f); 
    Node* A, * B, * C, * D; 
    for(size_t X=0 ; X<sizeX-1 ; X++)for(size_t Z=0 ; Z<sizeZ-1; Z++){ 
    A = &nodes[X*sizeZ+Z]; 
    B = &nodes[(X+1)*sizeZ+Z]; 
    C = &nodes[X*sizeZ+(Z+1)]; 
    D = &nodes[(X+1)*sizeZ+(Z+1)]; 
    glVertex3f(A->x, A->y, A->z); 
    glVertex3f(B->x, B->y, B->z); 
    glVertex3f(C->x, C->y, C->z); 

    glVertex3f(B->x, B->y, B->z); 
    glVertex3f(D->x, D->y, D->z); 
    glVertex3f(C->x, C->y, C->z); 
    } 
    glEnd(); 
}; 

Второй один:

void Grid::openglRender(){ 
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
    glBegin(GL_TRIANGLES); 
    glColor3f(1.0f, 1.0f, 0.0f); 
    for(size_t X=0 ; X<sizeX-1 ; X++)for(size_t Z=0 ; Z<sizeZ-1; Z++){ 
    glVertex3f(nodes[X*sizeZ+Z].x, nodes[X*sizeZ+Z].y, nodes[X*sizeZ+Z].z); 
    glVertex3f(nodes[(X+1)*sizeZ+Z].x, nodes[(X+1)*sizeZ+Z].y, nodes[(X+1)*sizeZ+Z].z); 
    glVertex3f(nodes[X*sizeZ+(Z+1)].x, nodes[X*sizeZ+(Z+1)].y, nodes[X*sizeZ+(Z+1)].z); 

    glVertex3f(nodes[(X+1)*sizeZ+Z].x, nodes[(X+1)*sizeZ+Z].y, nodes[(X+1)*sizeZ+Z].z); 
    glVertex3f(nodes[(X+1)*sizeZ+(Z+1)].x, nodes[(X+1)*sizeZ+(Z+1)].y, nodes[(X+1)*sizeZ+(Z+1)].z); 
    glVertex3f(nodes[X*sizeZ+(Z+1)].x, nodes[X*sizeZ+(Z+1)].y, nodes[X*sizeZ+(Z+1)].z); 
    } 
    glEnd(); 
}; 

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

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

может быть, это было бы немного лучше, если я объявляю X и Z перед тем, for петлями, чтобы избежать особенно декларации и разрушения sizeX времен Z

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

+2

Скорее всего, что накладные расходы на вызов 'glVertex3f (...)' *** far *** превосходят любые арифметические хаки-указатели для штанов, которые вы можете бросить на эту проблему. Существует буквально не смысл в микро-оптимизации немедленного режима, как это, вы должны переключиться на индексированные массивы вершин и назвать это время лучше потрачено. Но если вы настаиваете, вы можете сделать этот кошмар дольше, если вы выбросите 'glVertex3fv (... )' в микс для еще одной микро-оптимизации. –

+0

@ AndonM.Coleman звучит неплохо, чтобы быть честным Я никогда не использовал массив вершин, поэтому даже не думал об этом, когда писал этот код. Я немного читал о них в какой-то книге. Я буду читать больше об этом в библиотеке tomorow –

ответ

1
A = &nodes[X*sizeZ+Z]; 
B = &nodes[(X+1)*sizeZ+Z]; 
C = &nodes[X*sizeZ+(Z+1)]; 
D = &nodes[(X+1)*sizeZ+(Z+1)]; 

может быть

A = &nodes[X * sizeZ + Z]; 
B = A + sizeZ; 
C = A + 1; 
D = B + 1; 

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

(обязательное предупреждение о преждевременной оптимизации здесь. Если вы даже не замечая разницы между этими двумя, то это слишком рано, чтобы беспокоиться о микро-оптимизации.)

+0

Мне нравится, что я буду повторно использовать это –

0

Просто потому, что вы оптимизировать кусок кода Безразлично 'всегда означает, что вы увидите лучшую производительность во время выполнения. Как вы оцениваете производительность во время выполнения? В зависимости от количества итераций в двух циклах, вы, возможно, никогда не увидите разницу, если количество итераций достаточно велико. Какова фактическая величина sizeX и sizeZ?

+0

Actualy. Моя цель - получить несколько советов, чтобы писать более эффективно. Я не измеряю время выполнения. –

+1

Хотя всегда полезно убедиться, что вы пишете чистый и эффективный код, будьте осторожны, чтобы не попасть в ловушку «преждевременной оптимизации», что означает создание всех видов оптимизации кода, даже если это не требуется , Фактически это может сделать код менее понятным для других в некоторых случаях в зависимости от того, какие именно оптимизации вы делаете. – Andrew

+0

Да, я уже теряю время, пытаясь добиться чего-то лучшего. Я всегда стараюсь напомнить, что мне учил старый учитель, когда я был молод: «лучшее - это энтузиазм добра» (перевод с французского) –

0

Эти призывы устарели, это одна из причин, почему ваша программа работает медленно. Вместо этого вы должны посмотреть в VBO и шейдеры!

+0

Я читаю оранжевую книгу (шейдеры), но я действительно не понимаю, что должен быть написан в шейдере и что должно быть написано на C++, я знаю, что шейдер использует графический процессор, поэтому я спрашиваю себя, должно ли все, связанное с графикой, писать в шейдере. –

+0

@bobthemightyspellcaster: Нет, только те, которые используются для динамического вычисления, принадлежат шейдерам. Существует множество операций, которые все еще нужно выполнять только один раз во время загрузки. Я настоятельно рекомендую вам изучить этапы конвейера OpenGL перед тем, как переходить в шейдеры - шейдеры - это на самом деле миниатюрные программы, которые запускаются на графическом процессоре и вычисляют выходные данные для определенных этапов конвейера (например, этап преобразования вершин = вершинный шейдер, примитивный этап сборки = геометрический шейдер, этап растрирования = шейдер фрагмента). Как только вы понимаете поток трубопровода, шейдеры имеют больше смысла. –

+0

@bobthemightyspellcaster: ознакомьтесь с [этой статьей] (http://www.opengl.org/wiki/Rendering_Pipeline_Overview) для более подробной информации. –

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