Ostatnio trafiła mi się okazja analizowania problemu wydajnościowego, w którym (oprócz wolnego/nadmiarowego I/O - o tym może w innym mikroblogu) zauważalna była
nadmiarowa aktywność systemu (%sys z widoku narzędziampstat
). Zdrowy system nie powinien obciążać CPU swoimi aktywnościami w jakiś zauważalny sposób. Na potrzeby takich analiz przyjmuję wartość 10% (np. mając maszynę z 24 CPU, ~2 cpu można oddać kernelowi na zarządzanie systemem).
W tym przypadku aktywność systemu była na poziomie 10%-15%, więc warta sprawdzenia.
Po krótkiej analizie kilku procesów, okazało się, że 40%-60% czasu przetwarzania idzie na wywołanie stat()
.
Szybkie spojrzenie na wybrany proces i o dziwo, stat("/etc/localtime")
wywoływane było 800k razy w ciągu kilku sekund.
Po co ktoś miałby odwoływać się do /etc/localtime
i to 800k razy w ciągu kilku sekund? Takie pytanie zadałem sobie, zaś googla zapytałem o "excessive stat localtime".
Okazało się, że nie ja pierwszy zetknąłem się z tym problemem i jest ładnie opisany od strony technicznej.
W skrócie, funkcje zwracające localtime()
pobierają informacje o strefie czasowe i pobierają je właśnie z /etc/localtime
.
Remedium na takie zachowanie jest ustawienie zmiennej środowiskowej TZ
Szybkie ustawienie export TZ=:/etc/localtime
+ restart procesów i problem z nadmiernym stat()
został rozwiązany.
To tak w temacie dyskusji nt. wydajności języków programowania i ile da się wyciągnąć z hardware
This program generates around 31GiB of FizzBuzz per second
(comment) **This is really cool. Obviously didn't get a chance to understand much or any of it yet, but running it I'm getting 41-45GiB/s. **
I've spent months working on this program. I've long thought that "how fast can you make a FizzBuzz" would be a really interesting question for learning about high-performance programming, and when I subsequently saw this question posted on CGCC, I pretty much had to try
This program aims for the maximum possible single-threaded performance. In terms of the FizzBuzz calculation itself, it is intended to sustain a performance of 64 bytes of FizzBuzz per 4 clock cycles (and is future-proofed where possible to be able to run faster if the relevant processor bottleneck – L2 cache write speed – is ever removed).
On my computer (which has a fairly recent, but not particularly powerful, Intel processor), this program generates around 31GiB of FizzBuzz per second. I'll be interested to see how it does on the OP's computer.
High throughput Fizz Buzz @ codegolf.stackexchange.com
...
// Global variables.
.bss
.align 4 << 20
// The most important global variables are the IO buffers. There are
// two of these, each with 2MiB of memory allocated (not all of it is
// used, but putting them 2MiB apart allows us to simplify the page
// table; this gives a 30% speedup because page table contention is
// one of the main limiting factors on the performance).
io_buffers:
.zero 2 * (2 << 20)
// The remaining 2MiB of memory stores everything else:
iovec_base: // I/O config buffer for vmsplice(2) system call
.zero 16
error_write_buffer: // I/O data buffer for write(2) system call
.zero 1
.p2align 9,0
bytecode_storage: // the rest is a buffer for storing bytecode
.zero (2 << 20) - 512
// The program starts here. It doesn't use the standard library (or
// indeed any libraries), so the start point is _start, not main.
.text
.globl _start
_start:
// This is an AVX2 program, so check for AVX2 support by running an
// AVX2 command. This is a no-op, but generates SIGILL if AVX2 isn't
// supported.
vpand %ymm0, %ymm0, %ymm0
// Initialize constant registers to their constant values.
vmovdqa LINENO_LOW_INIT, [%rip + lineno_low_init]
vmovdqa LINENO_MID_BASE, [%rip + lineno_mid_base]
vmovdqa LINENO_TOP_MAX, [%rip + lineno_top_max]
vmovdqa ASCII_OFFSET, [%rip + ascii_offset]
vmovdqa BIASCII_OFFSET, [%rip + biascii_offset]
vmovdqa BASCII_OFFSET, [%rip + bascii_offset]
...
Isaac Gouy? Straszny dupek. Z tego co widzę to naklepał rozwiązanie w C, a nie w asmie: https://codegolf.stackexchange.com/a/215218 After much trial and error, with the goal of not resorting to Assembly while achieving the best single-threaded performance, this is my entry: ... Optimised the carry handling a bit, and now I'm getting ~3.9GiB/s on my machine (same configuration as above).
A to mogło mi się pomylić. Ten ais523 wygląda na kogoś kto mocno siedzi w esolangs - https://esoteric.codes/blog/interview-with-ais523
Kod Azure Active Directory obsługujący dziennie ok. 115 miliardów requestów w 53 centrach danych został podniesiony do
.NET Core 3.1 z Frameworka 4.6.2 i pozwoliło im to zejść z zapotrzebowania na 40 000 Corów do 20 000.
Więcej na ich temat na ich blogu: Azure Active Directory’s gateway is on .NET Core 3.1!
@Grzegorz Kotfis: ja już obecnie nie widzę powrotu do .NET Framework.
.NET Framework nie jest już rozwijany. Teraz będzie tylko .NET 5.
@Azarien: Miałem na myśli do pracy przy projektach opartych o .NET Framework a w szczególności WebForms, ASP.NET MVC.
Wrzucam zapowiedź podcastu z Konradem Kokosa o pamięci ...tej komputerowej ;)
W kilku słowach Konrad opowiada o odczycie sekwencyjnym i o tym, że jak sobie pościelisz tak się wyśpisz - tłumacząc: jak poukładasz obiekty w pamięci tak będzie szybko działać... jakoś tak ;)
Pełna publikacja w poniedziałek na https://devsession.pl
#podcast #programowanie #performance #wydajnosc
Szukasz prostego we wdrożeniu i wydajnego systemu buforowania danych? Przeczytaj artykuł wprowadzający do Memcached na naszym technicalblog: http://www.future-processing.pl/blog/memcached-and-php/ #memcached #performance #PHP
@vpiotr: typowa aplikacja przetwarzająca dane klientów w sposób batchowy, ale często operująca na funkcjach dotyczących czasu. Możliwe, że często generowała dane do logów i potrzebny był timestamp. Wygląda, że GLIBC sprawdzało aktualną strefę w /etc/localtime
@aolo23: ilość wywołań stat() spadła z 800k do 1. Co do wpływu na %sys, to sprawdzę czy okazji prac nad poprawą I/O.
