데이터 크기별 Zero-Copy 효과 비교

  • 대용량 메시지 (Image, PointCloud2, LaserScan 등 - 수 MB 단위)
    • 필수적 적용 대상: 2.76MB 이미지나 수십만 개 포인트의 라이다 데이터는 Deep Copy 발생 시 CPU 점유율이 급증하고, IPC 통신 버퍼 오버플로우로 프레임 드랍(4Hz 고꾸라짐 현상)이 발생합니다. UniquePtr + ConstSharedPtr 조합이 필수입니다.
  • 소용량 메시지 (PoseStamped, Twist, Imu, Int32 등 - 수 B ~ 수 KB 단위)
    • 기술적 적용 가능: geometry_msgs::msg::Twist 같은 제어 명령 데이터도 std::unique_ptr로 퍼블리시할 수 있습니다.
    • 실질적 이점 미미: 몇 바이트 남짓한 데이터는 memcpy 복사 시간이 나노초() 단위에 불과합니다. 따라서 굳이 포인터를 관리하는 오버헤드를 들이지 않고 기존 방

이미지를 발행할 때 (Publish)

// CvImage가 OpenCV Mat 데이터(`rect_img`)를 
// ROS2 sensor_msgs::msg::Image 포맷으로 변환한 뒤 
// 힙 메모리에 할당한 Raw 픽셀 데이터의 메모리 시작 주소.
auto shared_msg = cv_bridge::CvImage(header, "bgr8", rect_img_).toImageMsg();
// *shared_msg 역참조를 통해 기존 이미지 데이터를
// 새로운 힙 메모리 공간에 100% 그대로 복사(Deep Copy)한 뒤,
// 새롭게 생성된 메모리의 단독 시작 주소.
auto unique_msg = std::make_unique<sensor_msgs::msg::Image>(*shared_msg);
// unique_msg가 가진 메모리 주소의 독점 소유권을
// ROS2 RMW(미들웨어) 통신 파이프라인으로 완전히 이전(Move).
pub_rect_image_->publish(std::move(unique_msg));
  • 실제 담기는 내용: 픽셀 데이터가 저장된 힙(Heap) 메모리의 시작 주소값(Pointer)과 데이터 길이, 해상도 등의 메타데이터 정보.
  • std::move()의 역할: 2.76MB 픽셀 데이터를 새로 복사하는 것이 아니라, “내가 가지고 있던 힙 메모리 주소의 독점 소유권을 ROS2 RMW(미들웨어)로 넘겨주겠다”는 소유권 이동 명령입니다.

이미지를 구독할 때 (Subscribe)

ConstSharedPtr / SharedPtr

1. ConstSharedPtr 동작 방식 (True Zero-Copy)

[퍼블리셔 (camera_driver)]
   │ 1. std::make_unique<Image>() 생성 후 std::move()로 publish()
   ▼
[ROS2 IPC (통신 레이어)]
   │ 2. "수신자가 ConstSharedPtr(읽기 전용)이네? 메모리 수정 안 하겠군!"
   │ 3. 메모리 복사 없이 힙(Heap) 주소 그대로 전달
   ▼
[서브스크라이버 (FpsChecker)]
   │ 4. 퍼블리셔가 만든 원본 메모리 주소(Pointer)를 그대로 수신
  • 결과: 메모리 복사 횟수 0회.

2. SharedPtr 동작 방식 (Deep Copy 발생)

[퍼블리셔 (camera_driver)]
   │ 1. std::make_unique<Image>() 생성 후 std::move()로 publish()
   ▼
[ROS2 IPC (통신 레이어)]
   │ 2. "수신자가 SharedPtr(가변)을 요구하네? 원본 데이터를 수정할 수도 있겠어!"
   │ 3. 2.76MB 메모리를 새롭게 할당(malloc)받아 원본 데이터를 100% 그대로 복사(memcpy)
   ▼
[서브스크라이버 (FpsChecker)]
   │ 4. 새로 복사된 별도의 2.76MB 메모리 주소를 수신
  • 결과: ROS2 통신 레이어 내부에서 1회 메모리 복사(Deep Copy) 발생.
  • std::move(unique_msg)ConstSharedPtr를 통한 Zero-Copy는 한 프로세스(Component Container) 내부의 메모리 주소를 공유할 때만 성립하는 C++ 소프트웨어적 최적화.