Этому вопросу уже четыре года, и я немного удивлен, что никто еще не упомянул пропускную способность памяти. CPU-Z сообщает, что на моей машине установлена память PC3-10700. То, что RAM имеет пиковую пропускную способность (скорость передачи, пропускную способность и т. Д.), Составляет 10700 МБ / с. Процессор в моей машине - процессор i5-2430M с пиковой турбо частотой 3 ГГц.
Теоретически, с бесконечно быстрым процессором и моей оперативной памятью memcpy может иметь значение 5300 МБайт / с , то есть половину 10700, потому что memcpy должен считывать и затем записывать в RAM. (править: как указывал В.Одду, это упрощенное приближение).
С другой стороны, представьте, что у нас бесконечно быстрая оперативная память и реалистичный процессор, чего мы можем достичь? Давайте использовать мой процессор 3 ГГц в качестве примера. Если бы он мог выполнять 32-битное чтение и 32-битную запись каждый цикл, то он мог бы передавать 3e9 * 4 = 12000 МБайт / с . Это кажется легко доступным для современного процессора. Уже сейчас мы видим, что код, работающий на ЦП, на самом деле не является узким местом. Это одна из причин того, что современные машины имеют кэши данных.
Мы можем измерить, что на самом деле может делать процессор, измеряя memcpy, когда мы знаем, что данные кэшируются. Делать это точно - неудобно. Я сделал простое приложение, которое записывало случайные числа в массив, записывало их в другой массив, а затем проверяло сумму скопированных данных. Я прошел по коду в отладчике, чтобы убедиться, что умный компилятор не удалил копию. Изменение размера массива изменяет производительность кэша - маленькие массивы помещаются в кэш, а большие меньше. Я получил следующие результаты:
- 40 КБайт массивов: 16000 МБ / с
- 400 КБайт массивов: 11000 МБ / с
- 4000 КБайт массивов: 3100 МБ / с
Очевидно, что мой процессор может читать и записывать более 32 бит за цикл, поскольку 16000 - это больше, чем 12000, которые я рассчитал теоретически выше. Это означает, что процессор является еще более узким местом, чем я уже думал. Я использовал Visual Studio 2005 и, войдя в стандартную реализацию memcpy, я вижу, что она использует инструкцию movqda на моей машине. Я предполагаю, что это может читать и записывать 64 бита за цикл.
Хороший код, опубликованный hapalibashi, достигает 4200 МБ / с на моей машине - примерно на 40% быстрее, чем реализация VS 2005. Я предполагаю, что это быстрее, потому что он использует инструкцию предварительной выборки для повышения производительности кэша.
Таким образом, код, работающий на ЦП, не является узким местом, и его настройка приведет к небольшим улучшениям.