Я пытаюсь сократить время выполнения моей петли, которая в основном состоит из чтения данных в списке, выполнения некоторых вычислений и записи результата в массив.Итерация по списку и многопоточность
я попробовать эти тесты на список 20 000 000 элементов на Quad Core CPU:
- один поток для контура
- 4 нитей один цикл в каждой итерации резьбы 1/4 списка
Кажется, что один поток быстрее, чем 4 потока (я попробовал также с 2).
Мне было интересно, почему ??? Я думаю, проблема в пропускной способности ввода-вывода, но я действительно разочарован тем, что процессор используется на 25% и ждет вычисления.
Есть ли какое-либо решение для улучшения или параллелизации итерации по списку?
Является ли память ограничивающим фактором?
EDIT: Код добавлен
public class Main {
public static void main(String[] args) {
List<Integer> li = new ArrayList<Integer>();
IntStream.rangeClosed(1, 20_000_000).forEach(i -> li.add(i));
Integer[] tab = new Integer[1000];
IntStream.rangeClosed(0, 999).forEach(i -> tab[i] = 0);
System.out.println("debut");
Long start = System.currentTimeMillis();
Thread t1 = new Thread(new ThreadRunner(li, tab, 1, 0));
Thread t2 = new Thread(new ThreadRunner(li, tab, 4, 1));
Thread t3 = new Thread(new ThreadRunner(li, tab, 4, 2));
Thread t4 = new Thread(new ThreadRunner(li, tab, 4, 3));
t1.start();
t2.start();
t3.start();
t4.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("time : " + (System.currentTimeMillis() - start) + "ms");
}
}
public class ThreadRunner implements Runnable {
List<Integer> l;
private int inc;
private int start;
private Integer[] tab;
public ThreadRunner(List<Integer> l, Integer[] tab, int inc, int start) {
this.l = l;
this.inc = inc;
this.start = start;
this.tab = tab;
}
@Override
public void run() {
int fake = 0;
for(int i = start; i<l.size(); i+=inc){
fake = l.get(i);
}
System.out.println("fake : " + fake);
}
}
Делитесь кодом, пожалуйста. – RealSkeptic
Это * полностью * зависимый от кода и алгоритма. Во-первых, проблема должна заключаться в том, чтобы быть параллелизуемой. Затем необходимо использовать параллельный код, чтобы воспользоваться этим. – Makoto
Вы правы, я опубликую его как можно скорее. но он минималистский для цикла над списком и добавляет 1 к элементу массива (элемент выбирается с индексом списка по модулю 1000). Я запускаю 4 потока и жду с join(). Каждый цикл продвигает 4 элемента далее в списке – user43968