Хотя, конечно, можно превзойти компилятор при оптимизации, вы не собираетесь сделать это таким образом.Фрагменты, которые вы написали на ассемблере, являются довольно очевидными, механическими типами переводов, которые любой наполовину приличный компилятор (или даже довольно паршивый) может сделать легко.
Если вы хотите победить компилятор,вам нужно пойти намного дальше, например, переставить инструкции, чтобы позволить больше выполнять параллельно (решительно нетривиально), или найти лучшую последовательность команд, чем может компилятор.
В этом случае, например,Вы можете, по крайней мере, иметь шанс, заметив, что iarray[5][5][5]
может (с точки зрения языка ассемблера) рассматриваться как один плоский массив из 5 * 5 * 5 = 125 элементов и кодировать большую часть того, что по сути является memset
, вединственная инструкция:
mov ecx, 125 // 125 elements
xor eax, eax // set them to zero
mov di, offset ia_array // where we're going to store them
rep stosd // and fill that memory.
Реально, однако, это, вероятно, не будет значительным (или, возможно, даже незначительным) улучшением по сравнению с тем, что может сгенерировать компилятор.Скорее всего, оно близко к минимуму, необходимому (по крайней мере, почти), чтобы не отставать.
Следующим шагом будет рассмотрение вопроса о том, чтобы использовать временные хранилища вместо простого stosd
.Это на самом деле не ускорит этот цикл (во всяком случае, сильно), но в целом он может набрать некоторую скорость, избегая того, чтобы это хранилище загрязняло кеш, если возможно, что другой код, уже находящийся в кеше, сразу важнее.Вы также можете использовать некоторые другие инструкции SSE, чтобы набрать небольшую скорость, но даже в лучшем случае вы не можете ожидать намного лучше, чем пара процентов из этого.Суть в том, что для обнуления некоторой памяти скорость ограничивается, прежде всего, скоростью шины, а не инструкциями, которые вы используете, поэтому ничто из того, что вы делаете, скорее всего, не очень поможет.