Я пытаюсь понять, когда JDK будет автоматически векторизоваться. У меня есть следующий набор вопросов (несмотря на гугление, чтение, эксперименты и т.д.). Учитывая простой цикл следующим образом:
for(int i=0; size = size(); i < size; i++) {
a[i] = b[i] * c[i];
method1();
// someObject.method2();
// someHashMap.put(b[i], c[i]);
}
- Почему необходимо, чтобы вызов метода «method1» (который появляется в цикле) был встроен для автовекторизации? (Я не могу понять, почему это должно быть необходимым....)
- Возможно, это "глупый" вопрос, но что, если "someObject.method2()" раскомментировать. (И давайте предположим, что method2 - это огромный метод, т.е. много строк). Это также предотвратит автовекторизацию? Что, если бы method2 был крошечным методом (например, всего 1 или 2 строки и т. д.?)
- Что, если бы строка «someHashMap» была раскомментирована? Не приведет ли тот факт, что у нас есть объект/переменная, которые будут общими для всех SIMD, автовекторизация также не удастся? (Я не понимаю, как это могло бы работать, если бы jdk каким-то образом не вставлял ключевое слово «syncronization» автоматически при доступе к общему объекту/var «someHashMap»
- Мне кажется, что «потоковый» интерфейс решит проблему, подразумеваемую в вопросе № 3 непосредственно выше, поскольку логика «сборщика» в потоках автоматически позаботится об объединении отдельных хэш-карт, и поэтому нам не понадобится «синхронизированное» слово. (И в целом кажется, что потоковый API — это идеальный API, позволяющий jdk автоматически использовать автовекторизацию, если при создании потокового кода нет «внешних переменных» (т.е. нет побочных эффектов). /jit компилятор автоматически выполняет автовекторизацию в результате, когда код написан с использованием стандартного потокового интерфейса?Если нет, то не имеет ли смысла это делать (возможно, в будущей версии jdk или, возможно, jdk от какого-то другого поставщика?)
- Если тело цикла содержит много-много операторов if и т. д. (множество ветвлений и, скажем далее, что каждая ветвь выполняет много вычислений), означает ли это, что а) автовекторизация, вероятно, ПЛОХАЯ идея (точно так же, как это было бы для графического процессора ) и б) компилятор jit достаточно умен, чтобы определить, что автовекторизация - плохая идея, и поэтому он не будет автовекторизировать?
- В настоящее время я использую Oracle jdk8, но меняются ли ответы выше, если вы используете jdk9 или jdk10 и т. д.?
method1()
может изменить a[], b[] или c[], то, очевидно, он должен быть встроенным. Если escape-анализ может доказать, что массивы являются частными, то я уверен, что вы могли бы автоматически векторизовать и вызывать функцию 4 раза для каждого вектора SIMD, если бы ваш компилятор был достаточно умен, чтобы сделать это. Однако автовекторизация в JIT-компиляторе уже сложна (потому что она должна компилироваться быстро) по сравнению с опережающим C-компилятором. - person Peter Cordes   schedule 03.09.2018