3 ms·
I've worked on a single-machine computer vision system which used RabbitMQ to send messages around, including JPEG frames which were rather heavy, in contrast t
by bheadmaster 4y ago
I've worked on a single-machine computer vision system which used RabbitMQ to send messages around, including JPEG frames which were rather heavy, in contrast to other messages.
After we hit a certain number of frames/second, RabbitMQ became a bottleneck. My solution was to write the JPEG frame in the shared memory, then pass around shared memory ID, offset and frame length, instead of the whole frame. Only services that actually needed the frame would read it, others would just pass around a small JSON object. After that was implemented, the bottleneck disappeared.
I don't know if this qualifies as a "hack", but it certainly felt that way in the moment.
- hideo 4y agoWhat's really awesome about this is I think you independently discovered a huge trick in performance optimization. "Zero copy" solutions for eliminating the overhead of moving frames around are very popular - if you look up that term you'll see it pop up everywhere. Companies/teams of engineers spend months coming up with this solution and its a reliable way to reduce overhead of moving data around. It works across all layers and in fact entire hardware architectures are designed to allow for this kind of stuff. Kudos :)
- bheadmaster 4y agoThanks :)
- ltbarcly3 4y agoSingle machine ... RabbitMQ. Using jpg for events locally. Using jpg for computer vision. I think I see the problem, it's this entire thing.
- bheadmaster 4y agoMost USB cameras send JPEG frames because USB 2.0 isn't nearly enough to support raw frames: 60 frames/second * 1920*1080 pixels/frame * 4 bytes/pixel = ~475MiB/s, while maximum USB 2.0 bandwidth is ~60MiB/s. You also don't want to store raw frames on the cloud storage, your bill would skyrocket. Those are some of the reasons for using JPEG. If you're using dockerized services (which are a must for NVidia-based CV, since their CV libraries are a dependency hell), you must use some kind of networking solution to communicate. RabbitMQ might be considered overkill, but it does the job and is robust. It's not nice to talk that way about others' work, especially when your comment insults, but doesn't provide any insight whatsoever.
- deleted 4y ago[deleted]
- ltbarcly3 4y agoYea you're right of course, I was being glib. Glad it worked out in the end for you. For the record I don't think RabbitMQ was overkill, I think it's just way too much overhead to work for something like sending frames of video (which I think is the moral of your story). Anyway I'm guessing this was for a school project and you won't have to live with it so it's moot.
- bheadmaster 4y agoIt was actually a production system we built on my first job. It wasn't just sending frames from A to B, it did have a few moving parts. It eventually got stable and stopped changing, so in a way, I don't have to live with it. But it's up and running and does its job.
- lmm 4y ago> If you're using dockerized services (which are a must for NVidia-based CV, since their CV libraries are a dependency hell), you must use some kind of networking solution to communicate. Eithen the two processes can share memory, in which case they don't need to communicate via network, much less RabbitMQ, or they can't, in which case the hack wouldn't have worked at all.
- bheadmaster 4y agoGood point. I suppose what I meant to say is you need to communicate between processes somehow. Shared memory is fast, but it's hard to communicate with it exclusively - message-based protocols are better suited for that, and most of them are implemented over TCP.
- lmm 4y agoA lot of standard protocols can run over a unix domain socket, if you're not at the level of implementing a shared memory communication protocol but want to cut some overhead for more or less free.
- deleted 4y ago[deleted]