Распараллеливание вычислений в Go

Когда есть возможность разбить вычисление на отдельные части, которые можно выполнить независимо, тогда вычисление в Go можно распараллелить. При этом потребуется использовать каналы для сигнализирования о том, что та или иная часть вычисления завершается.

Представим, что у нас есть операция для вектора элементов, а значение операции для каждого элемента независимо по своей сути. Приведем пример (правда, немного идеализированный, но все же):

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

При этом вместо создания постоянных значений для numCPU, у нас есть возможность спросить среду выполнения, какое конкретно значение уместно. Здесь функция runtime.NumCPU будет возвращать число аппаратных ядер процессора на машине, следовательно, можно написать:

Кроме того, существует функция runtime.GOMAXPROCS, сообщающая (либо устанавливающая) указанное пользователем число ядер, которое способна запустить Golang-программа одновременно. По дефолту применяется значение runtime.NumCPU, однако его можно переопределить установкой одноименной переменной среды оболочки либо вызовом данной функции с положительным номером. Также следует отметить, что вызов этой функции с нулем просто запросит значение. Следовательно, если надо удовлетворить запрос ресурса пользователя, следует написать:

Главное, в чем следует убедиться, осваивая данную тему, -- что вы не путаете 2 основные идеи параллелизма:

  • параллелизма, как структурирования программы в качестве независимо выполняемых компонентов;
  • параллелизма как выполнения параллельных вычислений в целях повышения эффективности работы на нескольких ядрах процессора.

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

По материалам https://golang-blog.blogspot.com/.