2014-09-16 3 views
2

Я собираюсь прочитать большой файл csv и вернуть массив структур. Итак, я решил разбить большой файл на несколько меньших файлов с 1 миллионом строк и использовать процедуры для их параллельной обработки.параллельное распределение памяти с помощью `make`?

Внутри каждого работника, я создаю массив для вставки файлов строки в:

for i := 0; i < 10 ; i++ { 
    go func(index int) { 
     lines := make([]MyStruct, 1000000) 
    }(i) 
} 

Похоже ходу процедуры ждут друг друга на этой линии. Итак, если выделение памяти для массива занимает 1 секунду, 10 одновременных процедур, выполняющих это, будут занимать 10 секунд, а не 1 секунду!

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

+3

ли параметр переменной среды GOMAXPROCS? Если нет, по умолчанию Go будет использовать только одно ядро ​​ЦП. – siritinga

+0

@siritinga, что не улучшилось. После того, как я установил 'GOMAXPROCS', производительность не будет одинаковой при каждом прогоне. Возможно, это свидетельствует о том, что рабочие работают над разностными ядрами. Но это все еще очень медленнее, чем выделение памяти один раз. – sina

+1

Для чего это стоит, просто добавление большого старого фрагмента по мере того, как вы идете, может работать лучше, чем вы думаете: тестирование [для другого вопроса] (http://stackoverflow.com/questions/20251900/efficient-appending-to-a- variable-length-container-of-strings-golang), миллион, добавляемый к строке '[], занимает 77 мс. – twotwotwo

ответ

3

Вам необходимо установить runtime.GOMAXPROCS(runtime.NumCPU()) или GOMAXPROCS переменную окружения, чтобы на самом деле использовать несколько ядер.

исх: http://golang.org/pkg/runtime/#GOMAXPROCS

И цитировать @siritinga:

И, конечно же, вам нужно сделать что-то с линиями.

Прямо сейчас они выделяются, а затем теряются для сборщика мусора.

Другой подход заключается в заранее выделить срез затем передать его части к goroutines, например:

N := 1000000 
lines := make([]MyStruct, N * 10) 
for i := 0; i < 10 ; i++ { 
    idx := i * N 
    go func(lines []MyStruct) { 
     //do stuff with lines 
    }(lines[idx:idx+N]) 
} 
+1

И, конечно же, вам нужно что-то делать с линиями. Прямо сейчас они распределяются, а затем теряются для сборщика мусора. – siritinga

+1

@siritinga Я уверен, что он просто вырезал код для примера. – OneOfOne

+2

ну, это StackOverflow, вы никогда не знаете ...;) – siritinga

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