2015-03-22 2 views
0

Я пытаюсь сократить время выполнения моей петли, которая в основном состоит из чтения данных в списке, выполнения некоторых вычислений и записи результата в массив.Итерация по списку и многопоточность

я попробовать эти тесты на список 20 000 000 элементов на Quad Core CPU:

  1. один поток для контура
  2. 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); 

} 

}

+1

Делитесь кодом, пожалуйста. – RealSkeptic

+0

Это * полностью * зависимый от кода и алгоритма. Во-первых, проблема должна заключаться в том, чтобы быть параллелизуемой. Затем необходимо использовать параллельный код, чтобы воспользоваться этим. – Makoto

+0

Вы правы, я опубликую его как можно скорее. но он минималистский для цикла над списком и добавляет 1 к элементу массива (элемент выбирается с индексом списка по модулю 1000). Я запускаю 4 потока и жду с join(). Каждый цикл продвигает 4 элемента далее в списке – user43968

ответ

-2

Java не может решить, что ядро ​​использует. Ваша ОС примет такое решение. Таким образом, ваши 4 потока действительно работают на одном ядре.

+0

Мы этого не знаем точно. Пока код не будет добавлен. – Makoto

+0

Да, это хороший момент, о котором я не думаю, но я запускаю много тестов, и я видел увеличение загрузки процессора на 25% за счет добавленной темы – user43968

0

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

Что заставляет вас поверить, что это самая важная часть вашего кода для оптимизации, и что нереста потоков ускорит ее?

Помните правила Whe для оптимизации: http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize

Примечание: как вы измеряете время выполнения может так вводить в заблуждение вас. Написание микрообъектов очень сложно.

+0

Да, я понимаю.Но в реальном коде у меня гораздо больше вычислений в цикле for и с одним или 4 потоком у меня есть исполнение 2s, я не думаю, что накладные расходы на управление потоками занимают это время. Я действительно думаю, что память ils является лимитирующим фактором, и я хочу ваши мнения. – user43968

+0

Вы измеряли, где тратится время (возможно, с профилировщиком)? Кроме того, прочитайте https://code.google.com/p/caliper/wiki/JavaMicrobenchmarks перед написанием теста – NamshubWriter

Смежные вопросы