[an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive]
[an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive]![]() |
![]() |
![]() |
|||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
![]() |
![]() |
![]() |
> 1 - pthread (user + kernel) er bedre end msqX, men pthread (wall) er > dårligere. Linux straffer single process modellen? Jeg fandt en bedre pthread løsning, der opererer med read/write locks. Den ser ud til at være bedre i (sys+user) end shm1, men dårligere i (real) ved små transfervolumina. Den giver dog baghjul til shm1 (og de andre løsninger jeg prøvede) når det gælder for alvor. Hans-Christian Stadler ---------------------------------------- XXX_perf 2 64 512 1 1 ^løsning ^andtal modtagere ^antal buffere ^beskedsstørrelse ^dummy (extra work time) (dummy for msqX) msqX har buffere i kernen. Programmerne udfører 0x20000 gange en broadcast af en besked fra senderen til alle modtagere. Transfervolumen per message broadcast V_1 = modtagere * beskedsstørrelse Samlet transfervolumen V_tot = V_1 * 0x20000 Ved forsøget markeret med * svarer det til en båndbredde på ca. 63*10^6 bytes/s sslug@sslug:~/Projects/C++/ipc_test$ time ./pthread2_perf 2 64 512 1 1 real 0m1.493s user 0m0.376s sys 0m0.676s sslug@sslug:~/Projects/C++/ipc_test$ time ./pthread2_perf 2 4 512 1 1 real 0m1.474s user 0m0.367s sys 0m0.682s sslug@sslug:~/Projects/C++/ipc_test$ time ./shm1_perf 2 64 512 1 1 real 0m1.281s user 0m0.415s sys 0m0.817s sslug@sslug:~/Projects/C++/ipc_test$ time ./shm1_perf 2 4 512 1 1 real 0m1.440s user 0m0.445s sys 0m0.954s sslug@sslug:~/Projects/C++/ipc_test$ time ./pthread2_perf 128 64 512 1 1 * real 2m14.870s user 0m46.939s sys 1m27.193s sslug@sslug:~/Projects/C++/ipc_test$ time ./shm1_perf 128 64 512 1 1 real 2m42.906s user 1m10.247s sys 1m31.246s sslug@sslug:~/Projects/C++/ipc_test$ time ./msq1_perf 128 64 512 1 1 ---> msq2 kan ikke klare 128 modtagere real 3m10.784s user 0m44.416s sys 2m25.209s sslug@sslug:~/Projects/C++/ipc_test$ time ./msq2_perf 2 4 512 1 1 real 0m1.477s user 0m0.233s sys 0m1.211s --------------------------------------------------------------- Centralkoden i pthread2 løsningen. (Broadcast channel "chan" har en rwlock for hver af de "n_buffers" "data" buffere. Der skal være mindst 3 data buffere før det virker.) void* rcv_thread (void *arg) { int rcv_id = (int)arg; char *data = new char[chan->msg_size()]; int round = chan->n_buffers()-1; Sync lock1(chan->lock(round)); chan->wait_for_sender(lock1); pthread_barrier_wait(&barrier); do { round = (round + 1) % chan->n_buffers(); Sync lock2(chan->lock(round)); chan->wait_for_sender(lock2); <--- read lock // rlocks for round, previous round memcpy(data, chan->data(round), chan->msg_size()); chan->data_received(lock1); <--- unlock // rlock for round lock1.grab(lock2); if (receiver_work(rcv_id, data, chan->msg_size(), rcv_tm)) return NULL; } while (true); } void snd_thread (void) { char *data = new char[chan->msg_size()]; int round = 0, next_round; Sync lock1(chan->lock(round)); chan->wait_for_receivers(lock1); pthread_barrier_wait(&barrier); do { if (sender_work(data, chan->msg_size(), snd_tm)) return; next_round = (round + 1) % chan->n_buffers(); Sync lock2(chan->lock(next_round)); chan->wait_for_receivers(lock2); <--- write lock // wlocks for round, next_round memcpy(chan->data(round), data, chan->msg_size()); chan->send_data(lock1); <--- unlock // wlock for next_round lock1.grab(lock2); round = next_round; } while (true); }
![]() |
![]() |
![]() |
||||||||||||
|
||||||||||||||
![]() | ||||||||||||||
|
||||||||||||||
![]() |
![]() |
![]() |