Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use memcpy instead of std::copy when bridging images #565

Merged
merged 4 commits into from
Jun 27, 2024

Conversation

caguero
Copy link
Contributor

@caguero caguero commented Jun 24, 2024

🦟 Optimization

Summary

While testing ros <-> gz communication using the bridge I noticed that the bridge was talking quite a bit of time copying images from Gazebo to ROS. I found that the std::copy operation that we're doing is substantially slower than the memcpy alternative. I think that in principle this shouldn't happen but the numbers are quite clear. Perhaps std::copy is doing something that doesn't use cache effectively...

How to test it?

First, modify this code to see some stats:

auto beg = std::chrono::high_resolution_clock::now();
// Option 1: Using memcpy
// memcpy(ros_msg.data.data(), gz_msg.data().c_str(), gz_msg.data().size());

// Option 2: Using std::copy
auto count = ros_msg.step * ros_msg.height;
std::copy(
  gz_msg.data().begin(),
  gz_msg.data().begin() + count,
  ros_msg.data.begin());

auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - beg);
std::cerr << "Elapsed Time: " << duration.count() << " us" << std::endl; 

Recompile and launch one of our examples that publish 320x240 images:

ros2 launch ros_gz_sim_demos gpu_lidar_bridge.launch.py

The default code shows:

[parameter_bridge-2] Elapsed Time: 548 us

Enable the memcpy, comment the old code and relaunch the example again. The new code shows:

[parameter_bridge-2] Elapsed Time: 11 us

Checklist

  • Signed all commits for DCO
  • Added tests
  • Updated documentation (as needed)
  • Updated migration guide (as needed)
  • Consider updating Python bindings (if the library has them)
  • codecheck passed (See contributing)
  • All tests passed (See test coverage)
  • While waiting for a review on your PR, please help review another open pull request to support the maintainers

Note to maintainers: Remember to use Squash-Merge and edit the commit message to match the pull request summary while retaining Signed-off-by messages.

Signed-off-by: Carlos Agüero <[email protected]>
@caguero caguero requested a review from ahcorde as a code owner June 24, 2024 16:07
Signed-off-by: Carlos Agüero <[email protected]>
@traversaro
Copy link

traversaro commented Jun 24, 2024

Not blocking, but a comment on why std::copy may be slow: perhaps the type being copied is not trivially copiable? In theory this can be tested via a static_assert with std::is_trivially_copyable (that in theory may be a good thing to check even before using memcpy).

caguero and others added 2 commits June 24, 2024 20:58
Co-authored-by: Jose Luis Rivero <[email protected]>
Signed-off-by: Carlos Agüero <[email protected]>
Signed-off-by: Carlos Agüero <[email protected]>
@azeey
Copy link
Contributor

azeey commented Jun 24, 2024

CI seems to be broken on the ros2 branch. I'll be taking a look tomorrow.

@azeey azeey merged commit a781b78 into ros2 Jun 27, 2024
4 checks passed
@azeey azeey deleted the caguero/gz_ros_image branch June 27, 2024 15:44
@ahcorde
Copy link
Collaborator

ahcorde commented Aug 1, 2024

https://github.com/Mergifyio backport jazzy

Copy link
Contributor

mergify bot commented Aug 1, 2024

backport jazzy

✅ Backports have been created

mergify bot pushed a commit that referenced this pull request Aug 1, 2024
While testing ros <-> gz communication using the bridge I noticed that the bridge was talking quite a bit of time copying images from Gazebo to ROS. I found that the std::copy operation that we're doing is substantially slower than the memcpy alternative. I think that in principle this shouldn't happen but the numbers are quite clear. Perhaps std::copy is doing something that doesn't use cache effectively
---------

Signed-off-by: Carlos Agüero <[email protected]>
Signed-off-by: Carlos Agüero <[email protected]>
Co-authored-by: Jose Luis Rivero <[email protected]>
(cherry picked from commit a781b78)
ahcorde pushed a commit that referenced this pull request Aug 1, 2024
While testing ros <-> gz communication using the bridge I noticed that the bridge was talking quite a bit of time copying images from Gazebo to ROS. I found that the std::copy operation that we're doing is substantially slower than the memcpy alternative. I think that in principle this shouldn't happen but the numbers are quite clear. Perhaps std::copy is doing something that doesn't use cache effectively
---------

Signed-off-by: Carlos Agüero <[email protected]>
Signed-off-by: Carlos Agüero <[email protected]>
Co-authored-by: Jose Luis Rivero <[email protected]>
(cherry picked from commit a781b78)

Co-authored-by: Carlos Agüero <[email protected]>
Amronos pushed a commit to Amronos/ros_gz that referenced this pull request Sep 18, 2024
While testing ros <-> gz communication using the bridge I noticed that the bridge was talking quite a bit of time copying images from Gazebo to ROS. I found that the std::copy operation that we're doing is substantially slower than the memcpy alternative. I think that in principle this shouldn't happen but the numbers are quite clear. Perhaps std::copy is doing something that doesn't use cache effectively
---------

Signed-off-by: Carlos Agüero <[email protected]>
Signed-off-by: Carlos Agüero <[email protected]>
Co-authored-by: Jose Luis Rivero <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants