Problema
Estou observando que poll()
das chamadas estão tomando milissegundos quando são chamadas imediatamente após uma operação write()
, ainda levando apenas microssegundos quando chamadas imediatamente após uma operação read()
.
Isso está no código que usa a biblioteca de comunicação ACE C ++.
Estou tentando entender por que existe uma diferença tão significativa no tempo de CPU do sistema para chamar poll()
após uma chamada write()
em comparação com uma chamada read()
.
Sistema
[root@host ~]# lsb_release -a
LSB Version: :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: RedHatEnterpriseServer
Description: Red Hat Enterprise Linux Server release 5.9 (Tikanga)
Release: 5.9
Codename: Tikanga
strace
write(234, "[root@host ~]# lsb_release -a
LSB Version: :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: RedHatEnterpriseServer
Description: Red Hat Enterprise Linux Server release 5.9 (Tikanga)
Release: 5.9
Codename: Tikanga
S
write(234, "%pre%S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 256) = 256 <0.000048>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.006036>
read(234, "%pre%S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%
write(234, "%pre%S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 256) = 256 <0.000192>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.004996>
read(234, "S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%0%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%0%pre%%pre%"..., 256) = 256 <0.000076>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.000022>
read(234, "%pre%%pre%%pre%12%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%2%pre%%pre%%pre%%pre%%pre%1%pre%%pre%"..., 640) = 640 <0.000337>
write(234, "%pre%S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 256) = 256 <0.000096>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.004102>
read(234, "S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%!%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%!%pre%%pre%"..., 256) = 256 <0.000037>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.000157>
read(234, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%\t%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 289) = 289 <0.000047>
write(234, "%pre%S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 256) = 256 <0.000036>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.001882>
%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 256) = 256 <0.000048>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.006036>
read(234, "%pre%S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%
write(234, "%pre%S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 256) = 256 <0.000192>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.004996>
read(234, "S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%0%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%0%pre%%pre%"..., 256) = 256 <0.000076>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.000022>
read(234, "%pre%%pre%%pre%12%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%2%pre%%pre%%pre%%pre%%pre%1%pre%%pre%"..., 640) = 640 <0.000337>
write(234, "%pre%S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 256) = 256 <0.000096>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.004102>
read(234, "S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%!%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%!%pre%%pre%"..., 256) = 256 <0.000037>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.000157>
read(234, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%\t%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 289) = 289 <0.000047>
write(234, "%pre%S%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 256) = 256 <0.000036>
poll([{fd=234, events=POLLIN}], 1, -1) = 1 ([{fd=234, revents=POLLIN}]) <0.001882>
Discussão
Mesmo que a biblioteca ACE tenha uma opção para usá-la, provavelmente haverá pouco benefício em mudar para epoll()
porque poll()
está sendo chamado apenas com um descritor de arquivo nesse caso.
À medida que o sistema é carregado com 600 threads ímpares, essa chamada poll()
está consumindo cerca de 98% do tempo de CPU da chamada do sistema do processo envolvido. Então, estou procurando maneiras de tornar isso mais eficiente. Parece, no entanto, que chamar poll()
após um write()
é o problema, pois é consistentemente na ordem de 100x mais lenta do que após uma chamada read()
.