← 블로그 목록

[Core] 구조체 패딩 관련 내용

@J-unStiN
  • #Core
  • #Note
목차

안녕하세요. ThorVG 멘티 박성준 입니다. 구조체 패딩(Struct Padding) 최적화 작업에 대해 히스토리를 남기고자 글을 적게되었습니다. 앞으로 관련된 내용을 꾸준하게 올릴 수 있도록 하겠습니다.

이슈: https://github.com/thorvg/thorvg/issues/4618 PR: https://github.com/thorvg/thorvg/pull/4620

로그파일 build_wpadded_log.txt


패딩 경고를 보는 방법으로는 아래와 같이 진행했습니다.

1. -Wpadded 옵션을 포함하여 빌드 디렉터리 구성

meson setup builddir -Dcpp_args="-Wpadded" -Dc_args="-Wpadded"

2. 컴파일 경고를 포함하여 전체 빌드 로그를 텍스트 파일로 저장

ninja -C builddir > build_wpadded_log.txt 2>&1

예시: 발생한 패딩 경고 로그 일부

../src/renderer/tvgRender.h: warning: padding size of 'tvg::RenderDirtyRegion::Partition' with 7 bytes to alignment boundary [-Wpadded]
../src/renderer/tvgRender.h: warning: padding size of 'tvg::RenderStroke::Dash' with 4 bytes to alignment boundary [-Wpadded]
../src/renderer/tvgRender.h: warning: padding struct 'tvg::RenderEffectGaussianBlur' with 2 bytes to align 'sigma' [-Wpadded]
../src/renderer/tvgPaint.h: warning: padding size of 'tvg::Paint::Impl' with 63 bits to alignment boundary [-Wpadded]

3. 경고 종류

  • 멤버 간 정렬 패딩(우선순위): 큰 타입(8바이트 포인터 등) 앞에 작은 타입(1~2바이트)이 위치하여 발생
  • 구조체 끝 정렬 패딩: 구조체 전체 크기가 최대 멤버 정렬 단위의 배수가 되도록 끝에 패딩 삽입
  • jerryscript_jerry / rapidjson: 관련된 내용도 경고에 포함되어 있어 관련된 내용은 좀 더 파악해보기

작업전 내용 공유 + 파일 수정 범위

로그파일을 토대로 AI 에게 단계별로 분석했습니다. 해당 관련된 내용의 범위가 어느정도인지 정도로 보시면 좋을 것 같고, 작업전 파일을 정해 실제 경고로그에 파일이 있는 지 확인 후 진행하면 될 것 같습니다.

권장 작업 순서

  1. 1단계 독립 구조체부터 시작하여 멤버 변수를 정렬 크기 내림차순으로 재배치
  2. 2단계 리프 노드는 부모의 끝 패딩과 자식 첫 멤버의 관계를 확인 후 수정
  3. 3단계 부모 구조체는 전체 빌드 + 테스트로 자식 레이아웃 무결성 검증 필수
  • C++에서 구조체 멤버를 재배치할 때 상속 관계가 있는 구조체를 수정할 때는 주의가 필요합니다.
  • 부모 구조체의 멤버 순서를 바꾸면, 이를 상속받는 모든 자식 구조체의 메모리 레이아웃이 변경.

++ 작업후에는 꼭 테스트코드를 실행해서 문제없는 지 확인!!

ninja -C builddir test   // builddir == 빌드한폴더명
meson test -C builddir -v

분류 기준

단계설명수정 위험도
1단계 🟢상속받지 않은 독립적인 구조체낮음
2단계 🟡다른 구조체를 상속받지만, 자신은 더 이상 상속되지 않는 리프(Leaf) 노드중간
3단계 🔴부모이면서 자식들에 의해 상속되는 구조체 (복잡한 상속 계층)높음

2,001건의 경고가 발생했으며, ThorVG 자체 소스에서만 1,445건(고유 ~231건)이 확인.


주요 상속 계층 다이어그램

Renderer 계층

RenderEffect (3단계 🔴)
├── RenderEffectGaussianBlur (2단계 🟡)
├── RenderEffectDropShadow   (2단계 🟡)
├── RenderEffectFill         (2단계 🟡)
├── RenderEffectTint         (2단계 🟡)
└── RenderEffectTritone      (2단계 🟡)

RenderMethod (3단계 🔴)
└── SwRenderer               (2단계 🟡)

Task (3단계 🔴)
└── SwTask (3단계 🔴)
    ├── SwShapeTask           (2단계 🟡)
    └── SwImageTask           (2단계 🟡)

Paint (3단계 🔴, 공개 API)
├── Shape  → ShapeImpl       (2단계 🟡)
├── Picture → PictureImpl    (2단계 🟡)
├── Scene  → SceneImpl       (2단계 🟡)
└── Text   → TextImpl        (2단계 🟡)

Lottie Loader 계층

LottieObject (3단계 🔴) — 자식 18종 이상
├── LottieTextRange          (2단계 🟡)
├── LottieTrimpath           (2단계 🟡)
├── LottieRoundedCorner      (2단계 🟡)
├── LottieTransform          (2단계 🟡)
├── LottieImage              (2단계 🟡)
├── LottieAudio              (2단계 🟡)
├── LottieRepeater           (2단계 🟡)
├── LottieOffsetPath         (2단계 🟡)
├── LottiePuckerBloat        (2단계 🟡)
├── LottieZigZag             (2단계 🟡)

├── LottieSolid (3단계 🔴)
│   ├── LottieSolidFill      (2단계 🟡)
│   └── LottieSolidStroke    (2단계 🟡, 다중상속: +LottieStroke)

├── LottieGradient (3단계 🔴)
│   ├── LottieGradientFill   (2단계 🟡)
│   └── LottieGradientStroke (2단계 🟡, 다중상속: +LottieStroke)

├── LottieShape (3단계 🔴, 다중상속: +LottieRenderPooler)
│   ├── LottiePath           (2단계 🟡)
│   ├── LottieRect           (2단계 🟡)
│   ├── LottiePolyStar       (2단계 🟡)
│   └── LottieEllipse        (2단계 🟡)

└── LottieGroup (3단계 🔴, 다중상속: +LottieRenderPooler)
    └── LottieLayer          (2단계 🟡)


LottieEffect (3단계 🔴) — 자식 7종
├── LottieFxCustom           (2단계 🟡)
├── LottieFxFill             (2단계 🟡)
├── LottieFxStroke           (2단계 🟡)
├── LottieFxTint             (2단계 🟡)
├── LottieFxTritone          (2단계 🟡)
├── LottieFxDropShadow       (2단계 🟡)
└── LottieFxGaussianBlur     (2단계 🟡)


LottieModifier (3단계 🔴) — 자식 4종
├── LottieRoundnessModifier  (2단계 🟡)
├── LottieOffsetModifier     (2단계 🟡)
├── LottiePuckerBloatModifier(2단계 🟡)
└── LottieZigZagModifier     (2단계 🟡)


LottieProperty (3단계 🔴) — 자식 다수
├── LottieGenericProperty<T> (2단계 🟡, 5종 인스턴스)
├── LottieColorStop          (2단계 🟡)
└── LottieBitmap             (2단계 🟡)

Font / Raw Loader 계층

SfntGlyph (3단계 🔴)
└── SfntGlyphMetrics         (2단계 🟡)

SfntReader (3단계 🔴)
└── TtfReader                (2단계 🟡)

Loader → FontLoader
         └── SfntLoader      (2단계 🟡)

Loader → ImageLoader
         └── RawLoader       (2단계 🟡)

단계별 상세 목록

🟢 1단계: 독립 구조체 (상속 없음) — ~80개+

Renderer (src/renderer/)

구조체명파일패딩
RenderDirtyRegiontvgRender.h:1627B tail
RenderDirtyRegion::PartitiontvgRender.h:1987B tail
RenderTrimPathtvgRender.h:3323B tail
RenderStroketvgRender.h:3475B tail
RenderStroke::DashtvgRender.h:3524B tail
RenderShapetvgRender.h:3947B tail, 4B align
MasktvgPaint.h:377B tail
Paint::ImpltvgPaint.h:4463bits tail
Canvas::ImpltvgCanvas.h:307B tail
Fill::ImpltvgFill.h:351B tail
PictureOpstvgLoader.h:477B tail
FontMetricstvgLoader.h:1913B align
AccessorEntitytvgAccessor.h:344B align
TaskQueuetvgTaskScheduler.cpp:367B tail
TaskSchedulerImpltvgTaskScheduler.cpp:954B tail

CPU Engine (src/renderer/cpu_engine/)

구조체명파일패딩
SwOutlinetvgSwCommon.h:1017B tail
SwSpantvgSwCommon.h:1113B tail
SwFilltvgSwCommon.h:1691B tail
SwStrokeBordertvgSwCommon.h:1963B tail
SwStroketvgSwCommon.h:2093B tail, 4B align
SwDashStroketvgSwCommon.h:2282B tail
SwShapetvgSwCommon.h:2417B tail
SwImagetvgSwCommon.h:2523B tail
SwCellPooltvgSwCommon.h:3194B align
RleWorkertvgSwRle.cpp:2062B+4B+4B

SVG Loader (src/loaders/svg/)

구조체명파일패딩
SvgDocNodetvgSvgCommon.h:3054B tail
SvgSymbolNodetvgSvgCommon.h:3251B tail
SvgUseNodetvgSvgCommon.h:3376B tail
SvgRectNodetvgSvgCommon.h:3552B tail
SvgMaskNodetvgSvgCommon.h:3871B tail
SvgTextNodetvgSvgCommon.h:4004B tail
SvgCompositetvgSvgCommon.h:4587B tail
SvgPainttvgSvgCommon.h:4653B tail
SvgDashtvgSvgCommon.h:4754B tail
SvgStyleGradienttvgSvgCommon.h:4813B tail
SvgStyleFilltvgSvgCommon.h:5052B tail
SvgStyleStroketvgSvgCommon.h:5136B tail
SvgStylePropertytvgSvgCommon.h:5421B align
SvgNodetvgSvgCommon.h:5527B tail
SvgParsertvgSvgCommon.h:5865B tail
SvgParserContexttvgSvgCommon.h:6236B tail
unnamed structs (19개)tvgSvgLoader.cpp2~7B

Lottie Loader (src/loaders/lottie/) — 독립 구조체만

구조체명파일패딩
LottieStroketvgLottieModel.h:372B tail
LottieStroke::DashAttrtvgLottieModel.h:396B tail
LottieMasktvgLottieModel.h:2436B tail
LottieGlyphtvgLottieModel.h:3005B tail
LottieFonttvgLottieModel.h:4497B tail
LottieSlottvgLottieModel.h:11876B tail
LottieCompositiontvgLottieModel.h:12235B tail
LottieExpressiontvgLottieProperty.h:1277B tail
LottieScalarFrame<T> (9종)tvgLottieProperty.h:467B tail
LottieVectorFrame<Point>tvgLottieProperty.h:772B tail
LottieInterpolatortvgLottieInterpolator.h:284B tail
LottieTweentvgLottieTween.h:336B tail
RenderRepeatertvgLottieBuilder.h:361B tail
RenderTexttvgLottieBuilder.h:554B align
RenderContexttvgLottieBuilder.h:766B tail
PathSettvgLottieCommon.h:324B tail
TextDocumenttvgLottieCommon.h:713B tail

Common / Font / Public Header

구조체명파일패딩
Inlist<T> (7종)tvgInlist.h:374B tail
Map<uint,SfntGlyphMetrics>::ItemtvgMap.h:394B align
Paint (공개 API)thorvg.h:7844B align pImpl

🟡 2단계: 단순 상속 리프 노드 — ~55개

부모 구조체를 상속받지만, 자신은 더 이상 상속되지 않는다. 수정 시 부모의 끝 패딩이 자식 첫 멤버에 재활용되는지 확인필요.

Renderer 계층

구조체명부모파일패딩
RenderEffectGaussianBlurRenderEffecttvgRender.h:4825B tail, 2B align
RenderEffectDropShadowRenderEffecttvgRender.h:5013B tail, 2B align
RenderEffectFillRenderEffecttvgRender.h:5252B tail
RenderEffectTintRenderEffecttvgRender.h:5417B tail
RenderEffectTritoneRenderEffecttvgRender.h:5624B tail
SwSurfaceRenderSurfacetvgSwCommon.h:2797B tail
SwCompositorRenderCompositortvgSwCommon.h:3107B tail
SwShapeTaskSwTasktvgSwRenderer.cpp:927B tail
SwImageTaskSwTasktvgSwRenderer.cpp:1832B align
SwRendererRenderMethodtvgSwRenderer.h:366B align
ShapeImplShapetvgShape.h:337B tail
PictureImplPicturetvgPicture.h:346B tail
SceneImplScenetvgScene.h:315B tail
TextImplTexttvgText.h:353B tail
AccessorImplAccessortvgAccessor.cpp:357B tail

Lottie — LottieObject 자식

구조체명부모패딩
LottieTextRangeLottieObject3B+7B+6B
LottieTrimpathLottieObject7B tail, 6B align
LottieRoundedCornerLottieObject6B align
LottieTransformLottieObject6B align
LottieImageLottieObject7B tail, 6B align
LottieAudioLottieObject4B tail, 6B align
LottieRepeaterLottieObject7B tail, 6B align
LottieOffsetPathLottieObject7B tail, 6B align
LottiePuckerBloatLottieObject6B align
LottieZigZagLottieObject6B align

Lottie — LottieSolid/Gradient/Shape 리프

구조체명부모패딩
LottieSolidFillLottieSolid7B tail
LottieSolidStrokeLottieSolid + LottieStroke2B tail
LottieGradientFillLottieGradient5B tail
LottieGradientStrokeLottieGradient + LottieStroke2B tail
LottiePathLottieShape7B align
LottieRectLottieShape7B align
LottiePolyStarLottieShape7B tail
LottieEllipseLottieShape7B align
LottieLayerLottieGroup13bits+6B+3B

Lottie — LottieEffect/Modifier/Property 리프

구조체명부모패딩
LottieFxCustomLottieEffect4B align
LottieFxFill~GaussianBlur (6종)LottieEffect4B align
LottieRoundnessModifierLottieModifier3B align
LottieOffsetModifierLottieModifier3B tail
LottiePuckerBloatModifierLottieModifier3B align
LottieZigZagModifierLottieModifier3B tail
LottieGenericProperty<T> (5종)LottieProperty4~7B tail
LottieColorStopLottieProperty5B tail
LottieBitmapLottieProperty4B tail

Font / Raw / SVG Loader 리프

구조체명부모패딩
SfntGlyphMetricsSfntGlyph4B align
TtfReaderSfntReader4B tail
SfntLoaderFontLoader6B tail
RawLoaderImageLoader7B tail
SvgLoaderImageLoader + Task4B+3B align
LottieLoaderAnimLoader6B tail

🔴 3단계: 복잡한 상속 부모 — ~15개

Renderer 핵심 부모

구조체명자식 수파일패딩
RenderEffect5종tvgRender.h:4726B tail
RenderMethod3종tvgRender.h:5874B align key
Task다수tvgTaskScheduler.h:526B align prev
SwTask2종tvgSwRenderer.cpp:3820bits tail, 4B align
Picture1종thorvg.h:16107B tail

Lottie 핵심 부모

구조체명자식 수파일패딩
LottieObject18+tvgLottieModel.h:2536B tail
LottieShape4종tvgLottieModel.h:5917B tail
LottieSolid2종tvgLottieModel.h:7986B align
LottieGradient2종tvgLottieModel.h:8576B tail
LottieGroup1종tvgLottieModel.h:105251bits tail
LottieEffect7종tvgLottieModel.h:854B tail
LottieModifier4종tvgLottieModifier.h:317B tail
LottieProperty다수tvgLottieProperty.h:1566B align

Font Loader 부모

구조체명자식 수파일패딩
SfntGlyph1종tvgSfntReader.h:35— (자식이 패딩 발생)
SfntReader2종tvgSfntReader.h:48— (자식이 패딩 발생)

결론 - 진짜 해당 작업으로 크기가 줄어드는가??

image
  • 변수위치만 변경했는데 실제로 줄어들고 있습니다.

댓글

Discussion 원문