Страница 5 из 5
Go: TinyGo
Добавлено: 13 мар 2024, 23:40
Olej
Olej писал(а): ↑16 фев 2024, 03:07
Процессор то он задействовал 1
Возвращаясь в тему...
TinyGo
всегда использует только 1 процессор!
И если это нужно, то он диспетчирует N горутин на 1 процессор, подменяя параллельное выполнение конкурентным.
Новый, чуть исправленный вариант gorut.go:
Код: Выделить всё
package main
import (
"fmt"
"os"
"runtime"
"strconv"
"time"
)
func main() {
ветви := 5
debug := false
if len(os.Args) > 1 {
threads, err := strconv.Atoi(os.Args[1])
if err == nil {
ветви = threads
}
if ветви < 0 {
debug = true
ветви = -ветви
}
}
runtime.GOMAXPROCS(-1)
println("вижу процессоров: ", runtime.NumCPU())
const delay = 100
println("ветвей:", ветви, "длительностью:", delay, "ms")
done := make(chan bool)
t0 := time.Now()
for i := 0; i < ветви; i++ {
i := i
go func() {
defer func() {
done <- true
}()
t0, t1 := time.Now(), time.Now()
for t1.Sub(t0).Milliseconds() < delay {
t1 = time.Now()
}
if debug {
fmt.Printf("%02d завершился\n", i)
}
}()
}
for i := 0; i < ветви; i++ { // ожидание завершения всех
<-done
}
fmt.Printf("все %02d ветвей завершились, полное время: %v\n",
ветви, time.Now().Sub(t0))
}
Здесь мы запускаем на выполнение несколько однотипных горутин, каждая из которых выполняет активную «работу» (хотя и бессмысленную, но не переходя в блокированное состояние) на протяжении delay = 100 миллисекунд. Число запускаемых горутин можно определить числовым параметром команды запуска программы (если этот параметр задать со знаком минус, то дополнительно включится отладочный вывод, которым каждая горутина сообщит о своём завершении — тем самым мы можем наблюдать последовательность их завершения).
Go: TinyGo
Добавлено: 13 мар 2024, 23:43
Olej
Olej писал(а): ↑13 мар 2024, 23:40
Новый, чуть исправленный вариант gorut.go:
Сравительная (GoLang vs TinyGo) компиляция:
Код: Выделить всё
olej@nvidia:~$ go version
go version go1.18.1 linux/amd64
olej@nvidia:~/2024/Go$ go build -o gorutl gorut.go
Код: Выделить всё
olej@nvidia:~$ tinygo version
tinygo version 0.30.0 linux/amd64 (using go version go1.18.1 and LLVM version 16.0.1)
olej@nvidia:~/2024/Go$ tinygo build -o gorutt gorut.go
Код: Выделить всё
olej@nvidia:~/2024/Go$ ls -o gorut* | grep rwx
-rwxrwxr-x 1 olej 1795144 мар 13 17:24 gorutl
-rwxrwxr-x 1 olej 682928 мар 13 17:25 gorutt
Go: TinyGo
Добавлено: 14 мар 2024, 00:10
Olej
Olej писал(а): ↑13 мар 2024, 23:43
Сравительная (GoLang vs TinyGo) компиляция:
А теперь сравниваем...
- GoLang:
Код: Выделить всё
olej@nvidia:~/2024/Go$ ./gorutl
вижу процессоров: 4
ветвей: 5 длительностью: 100 ms
все 05 ветвей завершились, полное время: 111.851944ms
Код: Выделить всё
olej@nvidia:~/2024/Go$ ./gorutl 8
вижу процессоров: 4
ветвей: 8 длительностью: 100 ms
все 08 ветвей завершились, полное время: 137.347171ms
Код: Выделить всё
olej@nvidia:~/2024/Go$ ./gorutl 20
вижу процессоров: 4
ветвей: 20 длительностью: 100 ms
все 20 ветвей завершились, полное время: 199.403218ms
- TinyGo:
Код: Выделить всё
olej@nvidia:~/2024/Go$ ./gorutt
вижу процессоров: 1
ветвей: 5 длительностью: 100 ms
все 05 ветвей завершились, полное время: 501.129122ms
Код: Выделить всё
olej@nvidia:~/2024/Go$ ./gorutt 8
вижу процессоров: 1
ветвей: 8 длительностью: 100 ms
все 08 ветвей завершились, полное время: 803.195577ms
Код: Выделить всё
olej@nvidia:~/2024/Go$ ./gorutt 20
вижу процессоров: 1
ветвей: 20 длительностью: 100 ms
все 20 ветвей завершились, полное время: 2.005158872s
Отчётливо видно, что код GoLang выполняется за время близкое к delay (времени одной горутины) и даже мало зависит от числа горутин. Напротив, тот же код под TinyGo «видит» всегда только один процессор, а время выполнения N горутин равно N*delay, то есть последовательному их выполнению … независимо от того, вытесняю ли они друг друга, или выполняются чисто последовательно. Это и есть конкурентность взамен параллельности!
Go: TinyGo
Добавлено: 14 мар 2024, 00:12
Olej
Olej писал(а): ↑14 мар 2024, 00:10
А теперь сравниваем...
Любопытно сравнить ход выполнения и с включенным отладочным выводом:
Код: Выделить всё
olej@nvidia:~/2024/Go$ ./gorutl -7
вижу процессоров: 4
ветвей: 7 длительностью: 100 ms
02 завершился
06 завершился
01 завершился
00 завершился
03 завершился
04 завершился
05 завершился
все 07 ветвей завершились, полное время: 149.138321ms
Код: Выделить всё
olej@nvidia:~/2024/Go$ ./gorutt -7
вижу процессоров: 1
ветвей: 7 длительностью: 100 ms
00 завершился
01 завершился
02 завершился
03 завершился
04 завершился
05 завершился
06 завершился
все 07 ветвей завершились, полное время: 701.504755ms
В первом случае (GoLang) порядок завершения параллельных горутин хаотический, случайный, и он будет меняться от одного запуска программы к другой — и это, обычно, верный признак параллельного выполнения. Во втором случае (TinyGo) порядок завершения горутин детерминированный, последовательный, ровно в том же порядке как они и запускались — и это, зачастую, верный признак того, что перед нами конкурентное выполнение.
Go: TinyGo
Добавлено: 14 мар 2024, 00:16
Olej
Olej писал(а): ↑14 мар 2024, 00:10
- GoLang:
Ну и прогнать тот же код на 40 ядерном промышленном сервере ... любопытства ради:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/tinygo$ ./gorutl
вижу процессоров: 40
ветвей: 5 длительностью: 100 ms
все 05 ветвей завершились, полное время: 100.661022ms
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/tinygo$ ./gorutl 20
вижу процессоров: 40
ветвей: 20 длительностью: 100 ms
все 20 ветвей завершились, полное время: 103.836802ms
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/tinygo$ ./gorutl 40
вижу процессоров: 40
ветвей: 40 длительностью: 100 ms
все 40 ветвей завершились, полное время: 106.651848ms
Число горутин = числу процессоров - время выполнения всех 40 практически не отличается от времени нужного 1-й горутине (100ms).
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/tinygo$ ./gorutl 100
вижу процессоров: 40
ветвей: 100 длительностью: 100 ms
все 100 ветвей завершились, полное время: 234.563882ms
Даже 100 горутин (смешанный параллелизм с конкурентностью) укладываются во время исполнения всего в 2.34 раза длиннее одной горутины