Помните, что это
for (i = 0; i < sizeof(my_buffer); i++)
{
p[i] = 0;
}
также может быть быстрее, чем
for (i = 0; i < sizeof(my_buffer); i++)
{
*p++ = 0;
}
Как уже отвечалось, компилятор часто имеет ручные оптимизированные подпрограммы для memset () memcpy () и других строковых функций. И мы говорим значительно быстрее. теперь количество кода, количество инструкций, которые fast memcpy или memset из компилятора, обычно намного больше, чем предложенное вами решение цикла. меньше строк кода, меньше инструкций не означает быстрее.
Во всяком случае, мое сообщение попробуйте оба. разобрать код, увидеть разницу, попытаться понять, задать вопросы при переполнении стека, если вы этого не сделаете. а затем используйте таймер и время для двух решений, вызывайте любую функцию memcpy тысячи или сотни тысяч раз и измеряйте время целиком (чтобы устранить ошибку во времени). Удостоверьтесь, что вы делаете короткие копии, например, 7 или 5 элементов, и большие копии, например, сотни байтов на набор записей, и попробуйте использовать простые числа, пока вы в нем. На некоторых процессорах в некоторых системах ваш цикл может быть быстрее для нескольких элементов, таких как 3 или 5, или что-то в этом роде, очень быстро, хотя и медленно.
Вот один намек на производительность. Память DDR на вашем компьютере, вероятно, имеет ширину 64 бита и должна быть записана по 64 бита за раз, возможно, она имеет ecc, и вам нужно вычислять эти биты и записывать 72 бита за раз. Не всегда это точное число, но следуйте мысли здесь, это будет иметь смысл для 32 бит или 64 или 128 или что-то еще. Если вы выполняете однобайтовую инструкцию записи в оперативную память, аппаратному обеспечению потребуется выполнить одну из двух вещей, если на этом пути нет кэшей, система памяти должна выполнить 64-битное чтение, изменить один байт, а затем напиши это обратно. Без какой-либо аппаратной оптимизации запись 8 байтов в этой одной строке драм-памяти составляет 16 циклов памяти, и драм-память очень и очень медленная, не обманывайте себя числами 1333 МГц.
Теперь, если у вас есть кэш, для первой записи байта потребуется чтение строки кэша из dram, которая представляет собой одну или несколько из этих 64-битных операций чтения, следующие 7 или 15 или любые другие записи байтов, вероятно, будут очень быстро, так как они идут только в кеш, а не в ddr, в конце концов, эта строка кеша становится драмовой, медленной, так что один, два или четыре и т. д. из этих 64-битных или любых других ddr-местоположений. Таким образом, даже если вы только делаете записи, вам все равно нужно прочитать весь этот оперативный диск, а затем записать его, так что в два раза больше циклов, чем нужно. Если возможно, и это с некоторыми процессорами и системами памяти, memset или часть записи memcpy, могут быть одиночными инструкциями с целой строкой кэша или целым местоположением ddr, и нет необходимости в чтении, мгновенная удвоенная скорость. Это не то, как все оптимизации работают, но, надеюсь, даст вам представление о том, как думать о проблеме. Когда ваша программа помещается в кэш в строках кэша, вы можете удвоить или утроить количество выполненных инструкций, если взамен вы получите половину, четверть или более сокращений количества циклов DDR и вы выиграете в целом.
Как минимум, подпрограммы memset и memcpy компилятора будут выполнять байтовую операцию, если начальный адрес нечетный, тогда 16-битный, если не выровнен по 32-битному. Затем 32 бита, если не выровнены на 64 и выше, пока они не достигнут оптимального размера передачи для этого набора команд / системы. На руку они стремятся к 128 битам. Таким образом, наихудшим случаем на переднем конце будет один байт, затем одно половинное слово, затем несколько слов, а затем попадание в основной набор или цикл копирования. В случае передачи ARM 128 битов записано 128 битов на инструкцию. Затем на бэк-энде, если не выровнены, та же самая сделка, несколько слов, одно слово, один байт в худшем случае. Вы также увидите, что библиотеки делают что-то вроде: если число байтов меньше X, где X - небольшое число, например 13 или около того, то оно входит в цикл, подобный вашему, просто скопируйте несколько байтов, потому что количество инструкций и тактов поддерживать этот цикл меньше / быстрее. разберите или найдите исходный код gcc для ARM и, возможно, mips и некоторые другие хорошие процессоры, и посмотрите, о чем я говорю.