Pull to refresh
3
0
Дмитрий Вьюков @dvyukov

User

Send message
Tsan более тупой, но он не дает false positive. Он может пропустить ошибки, это да.
Если билд систему сложно менять, то можно сделать «compiler script»:
$ cat /xxx/g++
#!/usr/bin/env bash
clang++ -fsanitize=thread $@
$ export PATH=/xxx:$PATH
> Пауза зависит не только объема живых данных, но и от объема мертвых данных, не так ли?

Не так.
Смотрите ссылку выше — там все описано.

> GC должен бы запускаться более-менее равномерно при более-менее равномерной работе, а этого не происходит

Это действительно должно происходить. Не могу ничего сказать, т.к. у меня нет никаких данных.

> Согласитесь — куда предпочтительней иметь настройку максимального времени паузы

Не соглашусь.
Для non-concurrent mark&sweep GC такую гарантию нельзя обеспечить в общем случае. А там где можно, ее обеспечение может привести либо к чрезмерно большому потреблению памяти, либо к чрезмерно большому оверхеду на сборку мусора.
> Пулы ресурсов хорошо ложатся на архитектуру, но они помогут от GC, только если создание нового объекта требует много аллокаций/деаллокаций делать.

Пулы ресурсов помогают уменьшить частоту сборок мусора независимо от количества аллокаций при создании объекта. Однако пулы не уменьшают время сборки.
В Go сборка мусора запускается, когда объем мусора в куче равен объему живых объектов. Если переиспользуются старые объекты, то количество мусора не растет.
В Go 1.3 для пуллинга ресурсов появился специальный компонент sync.Pool.
> А есть гарантии, что уменьшение GOGC уменьшит максимальное время работы GC и разброс длительности паузы? Из документации мне это не очевидно. Но я протестирую, просто пока не было возможности.

Нет, точно так же как и для ручного вызова runtime.GC.
В 1.3 обе эти вещи не должны особо влиять на время паузы. Пауза в основном зависит от объема живых данных в программе. Вот тут я описывал это более подробно:
software.intel.com/en-us/blogs/2014/05/10/debugging-performance-issues-in-go-programs
> CGO присутствует, например для geoip, и тот же crypt(), но тут никуда не деться.

От этого никуда не деться, но это не значит, что их нужно делать в неимоверных количествах. Вызовы можно агрегировать прямо в Go файле как:

/*
#include «somelib.h»
void myWrapper(...) {
… malloc(...);
someLibCall1(...);
someLibCall2(...);
free(...)
}
*/
import «C»

C.myWrapper(...)

> На самом деле есть вариант без дедлока с апгрейдом через блокирующийся TryLock()

Не вижу, как это решает проблему изменившихся данных. И как будет выглядеть код? Если TryUpgrade провалился, то что? Мы все равно делаем RUnlock и Lock? Выглядит бессмысленно

> Пардон, но работать как-то нужно

Не понимаю связи. Работать — надо. Вызывать runtime.GC не надо. Вместо этого нужно уменьшить GOGC, что приведет к увеличению частоты сборок.

> Вычисления моего кода просто теряются на фоне задач, которыми приходится заниматься runtime

Это вполне может быть из-за неоптимальности кода программы. Например, cgocall/System занимает много времени, тк вы делаете 6 cgo вызовов вместо 1 или 2.

> Ещё больше расстраивает невозможность проапгрейдить блокировку RWMutex — если блокировка в статусе RLock и обнаружилось, что необходимо внести изменения — извольте делать RUnlock(), затем Lock() и ещё раз проверять, есть ли все ещё неоходимость делать эти изменения или какая-то горутина уже всё успела сделать.

Это принципиально нельзя сделать. Если 2 горутины захватили RLock, и пытаются проапгрейдить его до Lock, они дедлочатся. Все, что тут можно сделать, это собственно и есть RUnlock и Lock. И, да, данные могут поменяться, но от этого никуда не деться.

> Также нет неблокирующей функции TryLock()

Если нужно делать только TryLock, то это легко решается с помощью atomic.Swap(&x, 0, 1). Если нужно делать и TryLock и Lock, то, да, это считается слишком сложным для мьютексов,

> Решение — запускать GC() почаще, для надежности лучше самостоятельно из программы.

Этого ни в коем случае не надо делать. Если нужно, что бы GC запускался чаще, то нужно ставить переменную окружения GOGC в значение меньше 100. Хотя в 1.3 на время паузы это не должно особо влиять (тк sweep фаза происходит одновременнно с работой приложения), только уменьшать объем памяти

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity