128KB씩 잘라 여러 코어에 넘기고, 내보내는 것은 평범한 gzip, pigz 2.8
요약
입력을 작게 잘라 코어마다 나눠 맡기고, 나오는 것은 어느 풀기 도구든 읽는 평범한 파일이다. 풀기는 빨라지지 않고 -11은 시간과 맞바꾼다. 이 셈은 2.8 이후로 달라지지 않았다.
추천- 이름
- pigz
- 버전
- 2.8
- 요금
- 무료
- 오픈소스
- 오픈소스
- 운영체제
- Linux
- 공식 사이트
- https://zlib.net/pigz/
- 업데이트
- 2026-10-23 21:28
pigz는 gzip을 나눠 돌리는 구현으로 2007년 Mark Adler가 썼고, 이름은 parallel implementation of gzip의 앞 글자를 그대로 딴 것이다. 입력을 128 KB씩 잘라 여러 코어에 동시에 넘기고, 되쓰는 것은 하나의 평범한 gzip 파일이다. 공식 소스 자리에 걸린 판은 2.8이고 날짜는 2023년 8월 19일이다.
2.8 뒤로 판 번호가 삼 년 멈췄다
소스 자리에는 pigz source code version 2.8(19 Aug 2023)이라고 적혀 있고, 옆에 118K짜리 소스 꾸러미, 그 옆에 SHA-256 검증 값과 GPG 서명이 나란히 있다. 코드 저장소의 기록도 2023년 8월에 멈췄고, 마지막 기록의 설명은 한 줄, 판 번호 2.8이다.
새 판이 없다고 해서 기획이 멈춘 것은 아니다. DEFLATE의 형식은 오래전에 굳었고, 푸는 쪽은 온갖 체계에 흩어져 있다. 압축을 여러 코어에 나눠 맡기는 일만 하는 도구는 들어가는 것과 나오는 것이 그대로면 바꿀 이유가 없다. 2.8이 건드린 것은 세부였다. 고친 시간을 보통 파일에만 적기, 두 마디짜리 zlib 판 번호 받아들이기, 그리고 단언과 빈 지시자 주변의 작은 수선 몇 가지. 그런 수선이 끝나면 기능의 면은 닫힌다.
128 KB로 자르고, 사전을 부어 넣고, 다시 잇는다
방식은 돌아가지 않는다. 입력은 128 KB 덩어리로 잘리고, 각각 따로 압축되며, 각 덩어리의 검증 값도 그 김에 나란히 계산된다. 만들어진 조각은 쓰기 실이 원래 차례대로 잇고, 마무리에서 각 덩어리의 검증 값을 하나로 합친 뒤 gzip의 머리와 꼬리를 덮어쓴다. 그래서 나오는 것은 어느 풀기 도구든 알아보는 모양의 파일이고, 덩어리로 압축했다는 사실은 보이지 않는다.
덩어리 압축은 보통 압축률을 떨어뜨린다. 뒤 덩어리가 앞 덩어리의 앞뒤 맥락을 갖지 못하기 때문이다. 여기를 메우는 것이, 덩어리가 시작되기 전에 앞 덩어리의 마지막 32K를 미리 정한 사전으로 부어 넣는 손이다. 한 줄기 deflate가 공짜로 갖고 있던 이력 창을 그대로 옮겨 오는 셈이다. 이을 때는 각 덩어리가 바이트 경계에서 끝나야 해 네다섯 바이트의 군더더기가 붙는다. 백 킬로바이트가 넘는 덩어리에서는 무시할 만하다.
두 나사: 실의 수와 덩어리 크기
압축 실의 수는 기본으로 돌고 있는 처리기를 따르며 코어 수만큼 열린다. -p로 바꾸고, -p 1이라고 쓰면 실을 전혀 쓰지 않고 보통 gzip과 같은 길로 돌아간다. 덩어리 크기는 기본이 128K이고 -b로 바꾼다. 덩어리를 키우면 압축률이 나아지고 나란히 도는 정도가 나빠지며, 작게 하면 코어가 더 꽉 차고 압축률과 군더더기를 조금씩 내준다. 속도와 크기의 맞바꿈은 주로 이 둘로 한다.
주변에 요구하는 것이 적다. 공식 안내는 zlib과 pthread 두 가지에만 기대고 다른 곳의 코드를 끼워 넣지 않았다고 적는다. 그래서 여러 Unix 갈래의 체계에서 빌드된다. zlib은 적어도 1.2.3이어야 하고, 만든 쪽은 1.2.6 이후를 더 권한다. 덩어리 사이의 군더더기가 거기서 더 작게 눌리기 때문이다.
푸는 쪽은 나란히 가지 않는다
deflate의 흐름은 앞뒤가 물려 있어 푸는 쪽은 차례대로 갈 수밖에 없다. 압축할 때 각각 따로 풀리는 덩어리로 흐름을 잘라 두지 않았다면 말이다. 그래서 pigz가 풀 때 쓰는 주된 실은 하나이고, 그 밖에 읽기와 쓰기, 검증 계산을 위해 셋을 더 일으킨다. 어떤 경우에는 확실히 빨라지지만, 푸는 일을 코어마다 나눠 맡기는 것은 아니다. 모두 한 줄기로 돌리려면 -dp 1이나 -tp 1을 쓴다.
여기서 흔한 착각을 풀어 두자. pigz로 압축한 파일은 풀 때 빨라지지 않는다. 압축하는 쪽에서 아낀 시간은 푸는 쪽에서 되찾을 수 없다. 양쪽에서 이득을 보려면 압축할 때 아래에 적은 독립 덩어리 방식을 써야 한다.
-i가 사는 것은 건너뛰기와 견딤
-i나 --independent를 붙이면 덩어리끼리 사전을 참조하지 않고, 어느 덩어리든 따로 풀린다. 이득은 둘이다. 한 덩어리가 상해도 뒤쪽은 읽히고, 파일 중간으로 곧장 건너뛰는 데에도 처음부터 풀 필요가 없다. 푸는 쪽이 경계를 알도록 각 덩어리 앞에 아홉 바이트의 정해진 표시가 끼어든다. 열여섯 진법으로 00 00 FF FF 00 00 00 FF FF다. 값으로는 압축률이 덩어리 압축의 수준으로 돌아가고, 앞서 말한 사전의 보상은 사라진다.
-0에서 -11까지
압축 단계는 gzip과 같다. -0은 압축하지 않고 담고, -9가 가장 세게 가장 느리며, 기본은 -6에 떨어진다. pigz는 -11을 더한다. Jyrki Alakuijala의 zopfli 방식을 되풀이해 돌려 압축률을 몇 퍼센트 더 짜내지만 걸리는 시간은 뚜렷하게 늘어난다. 공식 안내의 표현대로 실행 시간에 무거운 값을 치른다. -11 둘레에는 전용 인자가 모여 있다. 되풀이 횟수는 기본 15, 덩어리의 최대 수도 기본 15이며, 자르지 않고 돌리거나 돌린 뒤 자르게 할 수도 있다.
출력 형식은 셋 중 하나다. 기본은 gzip, -z로 zlib의 .zz, -K로 항목 하나짜리 zip. 거기에 -R이 있어 자르는 자리를 입력 내용에 따르게 한다. 조금 고친 뒤 다시 압축해도 같은 부분이 같은 자리에 남아, 차분 전송이 움직인 곳만 나른다. 기록이나 보관을 한꺼번에 압축하듯 많은 양이 한 번에 흐르는 자리에서야 덩어리와 코어의 짝이 시간을 벌어 준다.
허락은 세 문장, 이름 읽는 법도 정해져 있다
허락은 zlib의 너그러운 형태다. 누구나 어떤 목적으로든 쓸 수 있고, 고칠 수 있고, 다시 나눠 줄 수 있다. 요구는 셋뿐이다. 자기가 썼다고 하지 말 것, 고친 판에는 표시할 것, 이 알림 문구를 지우지 말 것. Mark Adler는 zlib의 두 글쓴이 가운데 한 사람이기도 하고, zlib 사이트에는 푸는 쪽 절반을 그가 맡는다고 적혀 있다. pigz의 덩어리와 사전 수법은 그가 가진 그 보관함과 같은 서랍에서 나왔다.
이름을 어떻게 읽는지 공식이 따로 설명한다. pig-zee이지 pig의 복수가 아니다. 그런 물음이 첫 화면에 적혀 있다는 것 자체가 이 기획의 성질을 말해 준다. 안내는 한 장, 인자는 설명서 안, 나머지는 소스에 맡긴다.
압축을 여러 코어에 나누는 것이 pigz가 파는 유일한 것이고, 이십 년이 작은 수선으로 끝난 까닭이기도 하다. gzip의 형식이 바뀌지 않았으니 이 도구가 할 수 있는 일도 바뀌지 않았다. 솔직히 흠을 잡자면 푸는 쪽은 여전히 한 줄기이고, 빠른 것은 압축하는 쪽뿐이다.