요즘IT
위시켓
AIDP
콘텐츠프로덕트 밸리
요즘 작가들컬렉션물어봐
놀이터
콘텐츠
프로덕트 밸리
요즘 작가들
컬렉션
물어봐
놀이터
새로 나온
인기
개발
AI
IT서비스
기획
디자인
비즈니스
프로덕트
커리어
트렌드
스타트업
서비스 전체보기
위시켓요즘ITAIDP
고객 문의
02-6925-4867
10:00-18:00주말·공휴일 제외
yozm_help@wishket.com
요즘IT
요즘IT 소개작가 지원
기타 문의
콘텐츠 제안하기광고 상품 보기
요즘IT 슬랙봇크롬 확장 프로그램
이용약관
개인정보 처리방침
청소년보호정책
㈜위시켓
대표이사 : 박우범
서울특별시 강남구 테헤란로 211 3층 ㈜위시켓
사업자등록번호 : 209-81-57303
통신판매업신고 : 제2018-서울강남-02337 호
직업정보제공사업 신고번호 : J1200020180019
제호 : 요즘IT
발행인 : 박우범
편집인 : 노희선
청소년보호책임자 : 박우범
인터넷신문등록번호 : 서울,아54129
등록일 : 2022년 01월 23일
발행일 : 2021년 01월 10일
© 2013 Wishket Corp.
로그인
요즘IT 소개
콘텐츠 제안하기
광고 상품 보기
개발

프론트엔드에서 천만 개 데이터를 실시간으로 처리하는 법: WebGL과 GPGPU

FEConf
8분
1시간 전
206
에디터가 직접 고른 실무 인사이트 매주 목요일에 만나요.
newsletter_profile0명 뉴스레터 구독 중

FEConf2025에서 발표한 <프론트엔드에서 1,000만 개 데이터를 실시간으로 처리하라고요? WebGL2를 활용한 GPGPU의 세계로>를 정리한 글입니다. AI 기술의 확산으로 산업 전반에서 데이터의 규모와 중요성이 급격히 커지고 있습니다. 이에 따라 백엔드뿐만 아니라, 프론트엔드에서도, 브라우저상에서 대규모 데이터를 실시간으로 분석하고 시각화하려는 요구가 빠르게 증가하고 있는데요. 

 

이러한 흐름에 맞춰, GPU 가속을 활용해 브라우저 내에서 데이터를 효과적으로 처리하는 기술을 소개합니다. 본문에 삽입된 이미지의 출처는 모두 이 콘텐츠와 같은 제목의 발표 자료로, 따로 출처를 표기하지 않았습니다.

 

미리 요점만 콕 집어보면?

  • 기존 프론트엔드 라이브러리와 WASM으로는 천만~수천만 건 데이터의 실시간 처리에 한계가 있어, 새로운 접근이 필요했습니다.
  • WebGL을 활용한 GPGPU는 브라우저 호환성과 GPU 병렬 연산 덕분에, 대규모 데이터 필터링·렌더링에서 CPU 대비 확실한 성능 이점을 보였습니다.
  • 다만 정밀도 손실, 디버깅 난이도, GPU-CPU 병목, 수동 메모리 관리 등 현실적 제약을 이해하고 설계해야 효과를 극대화할 수 있습니다.
 

프론트엔드에서 1,000만 개 데이터를 실시간으로 처리하라고요? WebGL2를 활용한 GPGPU의 세계로

Portrai 김한슬마로

 

 

대규모 데이터 처리, 새로운 접근이 필요한 시점

저는 바이오테크 회사에서 대규모 데이터를 시각화하고 필터링할 수 있는 소프트웨어를 개발하고 있습니다. 조직 샘플을 스캔해서 어떤 세포들이 있고, 각 세포에 어떤 유전자가 얼마나 들어 있는지를 분석하는 데이터를 다루는데, 이 데이터의 양이 2019년 기준으로는 5만 개 수준이었다면 요즘 장비로는 같은 샘플에 대해 50배 이상의 데이터를 받아올 수 있게 되었습니다. 스캔 플랫폼의 해상도가 그만큼 높아진 것입니다.

 

 

문제는 기존에 있던 소프트웨어들이 이렇게 기하급수적으로 늘어난 데이터를 버티지 못하기 시작했다는 점입니다. 그래서 우리는 직접 도구를 만들어보기로 했습니다. 천만 개 이상의 데이터를 큰 딜레이 없이 렌더링하고, 여러 조건에 따라 실시간으로 필터링할 수 있어야 한다. 이것이 우리에게 주어진 개발 요구사항이었습니다.

 

처음에는 성능 좋기로 유명한 라이브러리들을 적용해보았습니다. 하지만 아무리 좋은 라이브러리라도 데이터가 몇백만 개 수준으로 늘어나면 속도가 눈에 띄게 느려졌습니다. 당연한 이야기지만 데이터가 많으면 많아질수록 반복문을 도는 시간도 길어집니다. 게다가 여러 라이브러리를 섞어 쓰다 보니 라이브러리마다 요구하는 데이터 타입이 달랐고, 각 라이브러리에 맞게 변환하는 것도 결국 반복문의 연속이었습니다. 속도 저하가 심각했습니다.

 

WebAssembly 기반 라이브러리도 시도해보았습니다. DuckDB WASM 같은 것들이 대표적인데, 여기서 WASM의 꽤 큰 단점을 알게 되었습니다. 컴파일된 WASM 바이너리의 크기가 5MB에서 20MB에 달했습니다. 요즘 웹 페이지가 3~4MB만 넘어가도 무겁다고 하는데, 20MB면 초기 로딩 시간이 꽤 오래 걸립니다. 더 흥미로운 점은 요즘 브라우저 성능이 많이 좋아져서 WebAssembly와 브라우저 자체 JavaScript 엔진의 성능 차이가 얼마 나지 않는다는 것이었습니다. WebAssembly의 장점이라고 했던 속도가 의미를 잃어버린 셈입니다.

 

그러다 문득 생각이 났습니다. 요즘 GPU로 연산하는 게 그렇게 핫하다던데. 한 번쯤 뉴스에서 비트코인 채굴하느라 그래픽 카드가 동났다는 이야기를 본 것 같고, 머신러닝 할 때도 GPU를 많이 쓴다고 합니다. GPU 연산이 상당히 빠르다는 의미일 것입니다. 그래서 우리도 이 GPU 연산, 즉 GPGPU를 한번 시도해보면 어떨까 생각하게 되었습니다.

 

 

GPGPU의 개념과 브라우저에서의 접근 방법

GPGPU란 무엇인가

GPGPU는 General Purpose Computing on Graphics Processing Unit의 약자로, GPU를 이용한 일반적인 계산을 의미합니다. 그래픽 카드는 원래 화면에 무언가를 그려주기 위해 존재하는 하드웨어지만, GPU로 연산을 하고 화면에 아무것도 그리지 않거나, 혹은 화면에 그리더라도 위치나 색깔 같은 것의 연산을 GPU로 처리하는 것도 범용적으로 GPGPU라고 부릅니다.

 

 

GPGPU를 위한 도구들을 찾아보니 CUDA 같은 것이 있었습니다. AI 관련 유튜브에서 한 번쯤 들어본 이름입니다. 최근에 나온 기술인 줄 알았는데 무려 2007년에 출시되었다고 합니다. 하지만 이런 CUDA를 브라우저에서 바로 쓸 수는 없습니다.

 

WebGL을 선택한 이유

브라우저에서는 공식적으로 두 가지 라이브러리를 통해 GPU에 접근할 수 있습니다. 하나는 WebGL이고, 다른 하나는 비교적 최근에 나온 WebGPU입니다. WebGL은 공식적으로 GPGPU를 지원하지 않지만, WebGPU는 GPGPU를 지원합니다.

 

그럼 WebGPU를 쓰면 되지 않느냐고 물을 수 있습니다. 하지만 브라우저 지원율을 보면 답이 나옵니다. WebGL은 전 세계 브라우저의 95% 이상에서 사용할 수 있는 반면, WebGPU는 70%에도 미치지 못합니다. 특히 Safari에서는 아직 지원하지 않습니다. 다음 버전에서는 지원할 예정이라고 하지만, 현시점에서는 불가능합니다. 여러 브라우저를 지원하기 위해 우리는 WebGL을 선택했습니다.

 

 

브라우저에서 GPU 연산은 어떻게 이루어지는가

브라우저에서 GPU 연산의 흐름은 생각보다 단순합니다. 먼저 연산할 데이터를 준비합니다. 이것은 배열 형태가 될 것입니다. 그다음 이 데이터를 GPU로 옮겨주어야 하는데, 이때 버퍼(GPU Buffer 또는 GL Buffer)라는 것을 생성해서 데이터를 넘깁니다.

 

여기서 생소한 개념이 등장합니다. Vertex Shader와 Fragment Shader입니다. 이 두 셰이더를 통해 GPU에서 연산이 이루어집니다. 연산 결과는 다시 GPU의 버퍼에 담기고, 최종적으로 HTML의 Canvas 엘리먼트에 렌더링됩니다. 만약 이 Canvas에 렌더링하지 않고 중간에 값을 가로챈다면, 화면에 그리지 않고 GPGPU를 했다고 할 수 있습니다.

 

 

셰이더는 GPU에서 연산을 하기 위해 실행되는 작은 프로그램입니다. GLSL이라는 C언어 계통의 언어로 작성해야 합니다. JavaScript 하기도 벅찬데 다른 언어까지 배워야 한다니 안타깝지만, 그것이 현실입니다.

 

Vertex Shader는 화면의 어떤 부분에 그림을 그릴지 정하는 연산을 담당합니다. `gl_Position`이나 `pointSize` 같은 값을 설정하는 코드를 볼 수 있습니다. 그다음 Vertex Shader를 통해 받아온 결과를 Fragment Shader로 넘겨서, 이번에는 화면에 어떤 색깔로 그릴지를 정합니다. `outColor`라는 벡터값으로 색상을 지정하는데, CSS에서는 0부터 255 사이의 값을 쓰지만 GPU에서는 0부터 1 사이의 float 값으로 표현합니다.

 

 

WebGL은 기본적으로 그래픽 라이브러리이기 때문에 용어들이 모두 그래픽을 위한 것들로 구성되어 있다는 점을 기억해야 합니다.

 

 

실제 성능 비교와 WebGL 코드 이해하기

CPU와 GPU, 실제 성능은 얼마나 차이가 날까

말로만 들어서는 실감이 나지 않을 것입니다. 쇼핑몰이라는 친숙한 테마로 데모를 만들어보았습니다. 왼쪽에서 필터를 지정하면 오른쪽에 결과가 실시간으로 나타나는 구조입니다. 백엔드 처리 없이 순수하게 프론트엔드에서만 처리합니다.

 

1만 개의 데이터로 시작해보겠습니다. CPU에서 연산하면 대략 2~3밀리초가 걸립니다. GPU로 바꾸면 오히려 조금 느려진 것처럼 보입니다. 이유는 나중에 설명하겠습니다.

 

 

이제 천만 개로 늘려보겠습니다. CPU에서 필터링하면 약 2.6~2.8초가 걸립니다. 같은 작업을 GPU로 하면 700밀리초 정도입니다. 눈에 띄게 빨라집니다. 더 극단적으로 3천만 개로 올려보겠습니다. CPU는 6초가 걸립니다. GPU는 3.9~4초 정도입니다. 확실히 CPU보다 훨씬 빠르다는 것을 체감할 수 있습니다.

 

왜 이런 속도 차이가 나는가

NVIDIA 컨퍼런스에서 보여준 그림이 이를 직관적으로 설명해줍니다. 위는 똑똑한 코어 하나가 그림을 한 땀 한 땀 그리고 있고, 아래쪽의 GPU는 여러 개의 코어가 그림을 한 방에 그려버립니다.

 

cpu 동작 예시

 

gpu 동작 예시

 

요즘 CPU는 코어 수가 많아야 10개에서 20개 정도입니다. 반면 GPU는 최신 제품 기준으로 1만 개에서 1만 5천 개의 코어를 가지고 있습니다. 단순한 연산의 경우 한 번에 병렬로 처리할 때 훨씬 빠를 수밖에 없습니다.

 

코드로 이해하는 WebGL의 핵심 개념

간단한 JavaScript 배열 연산을 WebGL 2로 작성하면 코드 양이 거의 30배가 됩니다. 어이가 없을 정도지만, 걱정할 필요는 없습니다. 보통 한 번만 작성하고 계속 재사용하기 때문에 프로덕션 레벨에서는 그 차이가 크지 않습니다.

 

 

모든 개념을 설명하기에는 시간이 부족하니 핵심만 추려보겠습니다. WebGL에는 세 가지 중요한 개념이 있습니다.

 

  • Attributes: 화면에 그릴 선들의 좌표를 담고 있습니다. GPGPU 관점에서 보면 반복문을 돌릴 때 사용하는 배열, 즉 데이터라고 생각하면 됩니다.
  • Uniforms: 연산할 때 공통적으로 사용할 상수입니다. 전역 상수라고 보면 됩니다.
  • Textures: 이미지 데이터를 의미합니다. 3D 게임에서 뼈대 위에 옷 같은 질감을 입힐 때 쓰는 것입니다. GPGPU 관점에서는 2차원 배열, 즉 데이터 테이블이라고 생각할 수 있습니다.

 

처음 보았을 때 엄청 길었던 코드가 이렇게 보니까 꽤 단순해 보입니다.

 

 

 

GPGPU 개발 과정에서 마주한 현실적인 문제들

데이터를 중간에 바꾸기 어렵다

JavaScript에서는 반복문 안에서 배열 데이터를 실시간으로 바꿀 수 있습니다. 하지만 WebGL에서는 이렇게 하기가 쉽지 않습니다. 다른 우회 방법들이 필요합니다.

 

 

부동소수점 정밀도 문제

GPU에서는 기본적으로 32비트 숫자를 지원합니다. 하지만 JavaScript의 숫자는 64비트입니다. 이를 변환하면 값이 바뀌거나 소실될 수 있습니다. Float64에서 Float32로 변환하는 과정에서 정밀도 손실이 발생할 수 있으므로 주의가 필요합니다.

 

 

디버깅의 고통과 LLM의 도움

에러 메시지를 보아도 원인을 알기 어려울 때가 많습니다. 어떤 때는 에러조차 보여주지 않습니다. 물론 JavaScript도 디버깅이 어렵기는 하지만, 다행히 LLM 덕분에 많은 도움을 받을 수 있었습니다.

 

WebGL 2를 사용한다면 이를 명확히 언급해야 합니다. LLM이 최신 WebGPU를 사용해보지 않겠냐며 엉뚱한 코드를 생성하는 경우가 많기 때문입니다. "WebGL 2를 사용해서 구현해줘" 또는 "WebGPU로 작성해줘"처럼 명확하게 명시하는 것이 좋습니다.

 

GPU-CPU 간 데이터 이동 병목 현상

아까 1만 개 데이터에서 CPU가 더 빨랐던 이유가 바로 이것입니다. GPU 연산 결과를 CPU로 옮겨올 때 병목이 발생합니다. TypedArray를 GPU 버퍼로 변환하고, 연산을 실행한 다음, 결과를 CPU로 가져올 때 상당한 오버헤드가 발생하는 것입니다.

 

 

만약 이런 연산을 여러 번 해야 한다면, GPU로 옮기고 → 계산하고 → CPU로 가져오고를 반복하면서 병목이 계속 누적됩니다. 이를 해결하는 방법이핑퐁(Ping-Pong) 기법입니다. 결과를 CPU로 바로 가져오지 않고 다시 입력 버퍼로 넘겨서 GPU 내부에서 연산을 계속 이어갑니다. 최종적으로 값을 가져올 때 병목을 한 번만 견디면 되니 시간이 크게 단축됩니다.

 

수동 메모리 관리의 필요성

브라우저는 기본적으로 가비지 컬렉터를 통해 메모리를 자동으로 관리해주지만, GPU에서는 직접 해야 합니다. 버퍼를 무한정 생성하고 삭제하지 않으면 메모리 이슈가 발생할 수 있습니다. 사용한 버퍼와 텍스처는 반드시 명시적으로 삭제해주어야 합니다.

 

 

텍스처 크기 제한

텍스처, 즉 데이터 테이블의 크기는 제한되어 있습니다. 한꺼번에 너무 많은 데이터를 넘기면 에러가 발생하면서 연산이 아예 안 될 수 있습니다.

 

비트패킹으로 메모리를 32배 절약하기

GPU에서는 Boolean 값이 기본적으로 4바이트를 차지합니다. 관리 효율성 때문이라고 합니다. true는 1, false는 0인데 한 칸만 사용하고 나머지 31칸은 낭비하는 셈입니다. GPU는 메모리가 상대적으로 적은 편인데 이것은 비효율적입니다.

 

이를 해결하기 위해 비트패킹을 사용합니다. 숫자 하나를 선언하고(4바이트 = 32비트), 각 비트에 Boolean 값들을 넣는 것입니다. 공간을 32배 절약할 수 있습니다. 옛날 팩 게임들이 40KB, 1MB 안에 모든 것을 욱여넣었던 것처럼 말입니다.

 

 

 

GPGPU, 이제는 프론트엔드에서 시도해 볼만한 기술

예전에는 WebGL 자체의 기능도 제약이 많았지만, 요즘은 브라우저에서 계속 기능을 추가해주고 기본적으로 하드웨어 성능이 좋아지면서 효과가 큽니다. 노트북에 들어가는 GPU 성능도 점점 향상되고 있습니다. GPT-4 때만 해도 GPGPU 관련 질문에 제대로 된 답변을 얻기 어려웠는데, GPT-5 출시 이후에는 꽤 정확한 답변을 받을 수 있게 되었습니다. LLM의 도움을 받기 좋은 환경이 갖춰진 셈입니다.

 

어디에 적용하면 좋을까?

  • 대규모 데이터를 다룰 때: 수백만, 수천만 개의 데이터를 실시간으로 필터링하고 시각화해야 하는 경우에 GPGPU는 큰 효과를 발휘합니다.
  • 오프라인 퍼스트 앱: 기본적으로 데이터를 브라우저에 저장하기 때문에 백엔드를 거치지 않고 빠르게 연산해야 합니다. GPGPU가 특히 유용합니다.
  • 증권 앱: 몇몇 증권 앱을 보니 처음 실행할 때 데이터를 미리 로컬에 다운로드하는 경우가 많았습니다. 증권 데이터는 숫자가 실시간으로 변하기 때문에 GPGPU를 활용하면 속도 개선에 큰 의미가 있을 것입니다.

 

프론트엔드에서 GPGPU는 이제 충분히 시도해 볼 만한 기술이 되었습니다. 초기 러닝 커브가 있지만, 성능 개선 효과는 그 노력을 충분히 보상해 줄 겁니다.

 

©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.