2014-02-13 4 views
0

Мне нужен простой и переносимый способ явной предварительной выборки данных. Я не хочу использовать конкретную функцию какого-либо конкретного компилятора или платформы, просто что-то общее, чтобы работать на разных платформах и компиляторах.Переносная явная предварительная выборка

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

+0

Вам нужно следить за тем, как компилятор оптимизирует вашу память, так как будет думать, что они ничего не делают. –

+0

Нет никакого переносимого способа сделать это в c или C++, потому что нет гарантии, что вы компилируете собственный код на машине регистрации. например интерпретируется C++ - http://root.cern.ch/drupal/content/cling и компиляция в jvm - http://nestedvm.ibex.org – user1937198

+0

'_mm_prefetch' должна быть достаточно переносимой. Вопреки тому, что говорит на странице MSDN, встроенные функции SSE не являются специфичными для Microsoft и доступны по крайней мере из нескольких наиболее популярных компиляторов (GCC, Clang, Intel, MSVC). – user2802841

ответ

3

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

  1. упреждающих выборка недопустимого адреса не вызывают ошибки в то время как при попытке чтения, записи или выполнить недопустимый адрес генерирует ошибку (если процессор имеет MPU/MMU, конечно).
  2. Предварительная выборка может быть сделана для чтения и/или записи, тогда как просто чтение байта в регистр просто чтение байта в регистр.
  3. Вы можете (теоретически) определить местность памяти при предварительной выборке.
  4. У процессора могут быть специальные инструкции для предварительной выборки, которые не совпадают с инструкциями загрузки памяти.

Так что просто придерживайтесь __builtin_prefetch и дайте компилятору тяжелую работу.

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

Еще одна интересная вещь: в общем, явная предварительная выборка не улучшает производительность, но немного ухудшает ее. См. this LWN article для получения дополнительной информации и объяснений, почему предварительная выборка была полностью удалена из ядра Linux.

Надеюсь, это поможет. Удачи!

+0

Я хочу, чтобы предварительный выбор следующего узла при обработке текущего, я не думаю, что компиляторы выглядят так «вперед». Узлы не являются последовательными в памяти, поэтому я не ожидаю, что аппаратные префетеры процессора тоже будут полезны. – dtech

+0

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

+0

@ddriver Делает это не переносным способом ('__builtin_prefetch' и т. Д.) Приводит к любой скорости? В противном случае мало смысла думать о большинстве переносных способов. В моем ограниченном опыте каждый раз, когда я использовал предварительную выборку вручную, он становился медленнее или почти одинаковым. – user2802841