윈도우에서 절전 모드로 설정했는데, 곧바로 다시 켜지거나, 문득 확인해보면 전원이 들어와 있을 때가 있다.

 

구글링하면 장치 관리자의 몇몇 장치 속성에서  '이 장치를 사용하여 컴퓨터의 대기 모드를 종료할 수 있음'을 체크 해제하라고 한다.

 

그런데 어떤 장치에 대해 체크 해제할까?

 

어떤 장치가 시스템을 깨울 수 있는지 cmd에서 직접 확인하면 된다.

아래 상자에 마이크로 소프트의 답변을 옮겨놓는다.

  1. Windows 로고키 + X키를 누른 후 명령 프롬프트(관리자)를 클릭합니다.
    이 후 사용자 계정 컨트롤 메시지창이 표시되면 '예'를 클릭합니다.
  2. 명령 프롬프트(관리자)가 실행되면 아래의 명령어를 입력 후 Enter 합니다.
    powercfg -devicequery wake_armed
  3. 나타나는 목록을 확인합니다.
  4. 이 후 [제어판 - 시스템 및 보안 - 시스템 - 장치 관리자]를 클릭한 후 해당 장치들을 찾아 더블 클릭합니다.
  5. 속성 창이 나타나면 전원 관리 탭으로 이동한 후 '이 장치를 사용하여 컴퓨터의 대기 모드를 종료할 수 있음' 을 체크 해제한 후 확인 버튼을 클릭합니다.
  6. 이 후 증상을 확인합니다.

 

내 시스템의 경우 위처럼 다른 것들은 다 끄고 랜카드 하나 남겨놓았다.

마우스의 경우 대기 모드 종료가 가능하게 해 놓으면, 책상이 잠깐 흔들리면 시스템 전원이 켜지기도 한다.

 

그런데 문제는 원격 접속을 하고 싶은데 랜카드가 대기 모드를 종료할 수 없도록 하면 골치아파진다.

 

이 때는 위의 그림처럼 '매직패킷'에서만 대기모드를 종료할 수 있도록 해준다.

 

그렇게 되면 임의의 다른 신호로 부팅되는 일은 없다.

물론 WOL을 설정해줘서, 원격에서 시스템을 켜고 싶으면 wol 을 이용해서 시스템을 켜면 된다.

그 이후에는 RDP 등 원격 접속 가능.

 

원격에서 사용을 다 했으면, 다시 절전 모드로 꺼 놓고, 

필요할 때 wol로 켜고 원격 접속하면 된다.

 

윈도우 11을 사용중인데, SSD -> SSD 복사 속도가 말도 안되게 느려졌다.

150MB/s 가 나오지 않을 때도 있다.

캐시 한계를 넘어서는 순간 느려지는 문제도 아니고 그냥 처음부터 느리다.

아주 가끔 1GB/s 정도가 나올 때도 있다. 원래 안 그랬던 것 같은데.

모두 로컬에 물린 SSD 이고, HEDT 사용중이라 SSD 두개 다 CPU와 PCIE 4.0x 4 채널로 연결되어 있다. 다시 말해 칩셋에 물린 레인을 타서 병목이 걸리는 상황도 아니다.

 

크리스탈인포디스크 등으로 체크해봐도 문제가 없고, 삼성 매지션 등 단순 디스크 벤치마킹에서는 정상 속도가 나온다. 읽기 기준 7500MB/s 정도.

그리고 10GbE x 2로 NAS로 직결해서 사용중인데, SSD와 SMB 방식 복사에서는 1.6GB/s 정도 나온다. 정상이다.

 

찾다보니 윈도우 11 탐색기 복사 문제인 것을 알게 되었다.

cmd에서 XCOPY로 복사하니 정상 속도가 나온다.

 

아래 글을 보면, 문제가 있었고, 해결했다고 하는데 2024년 2월 시점에 여전히 안되는 것 같다.

https://www.pcworld.com/article/2033072/windows-11-update-fixes-annoying-ssd-bug-finally-full-speed-again.html

 

Windows 11 update fixes annoying SSD slowdown bug

Windows 11 users have been complaining for months about a bug that halved the speed of SSDs. Now there's a fix.

www.pcworld.com

 

 

일단 SSD 복사 속도가 너무 느려서 검색하다 이 글로 찾아온 분들이 있다면,

같은 문제인지 테스트해볼 수 있다.

 

  • robocopy \\someserver\somesharec:\somefolder somefile.img /J
  • xcopy \\someserver\somesharec:\somefolder /J

cmd를 실행시켜 위의 명령어 중 하나로 테스트해보자. 작업 관리자 등을 띄워놓고 큰 파일을 xcopy등으로 복사한 뒤, 디스크 사용 속도가 정상적으로 나오는지 관찰해보면 된다.

윈도우 시스템 파일이 손상 되었을 때, 복구하는 방법

 

1. 윈도우 설치 파일 준비 

마이크로소프트 홈페이지에서 설치 파일을 다운받는다.

USB에 설치 미디어로 만들거나, iso 를 다운받아서 가상 시디로 마운트 시켜도 된다.

당연히 현재 설치된 버젼과 동일한 윈도우를 준비해야 한다.

 

2. install.esd를 install.wim으로 변환하기

cmd를 관리자 권한으로 실행시킨다.

명령 프롬프트에 다음과 같이 입력한다.

dism.exe /esport-image /sourceImageFile:E:\source\install.esd /sourceIndex:3 /DestinationImageFile:d:\wim\install.wim

 

여기서,

E:\source\install.esd 는 바로 위에서 다운받은 설치 미디어 파일이 있는 드라이브다. iso를 다운받아 마운트 시키지 않고 압축을 풀어도 되는데, 여튼, 설치 미디어의 source 폴더 밑에 install.esd 가 있는 것을 확인할 수 있다. 3메가 정도 파일이다.

 

그리고,

/sourceIndex:3 

에서 3번 인덱스는 win pro 버젼을 가리킨다. 경우에 따라 pro 버젼이 아니거나 인덱스가 달라질 수도 있는데, 그 인덱스는  역시 명령프롬프트에서 아래의 명령어로 확인하면 된다.

 

dism.exe /Get-Wiminfo /Wimfile:e:\sources\install.esd

 

설치 파일 정보를 읽으면서 몇번 인덱스에 어떤 운영체제가 들어있는지 화면에 출력해준다.

 

그리고,

d:\wim\install.wim 부분은 esd를 wim으로 변환시킨 후 저장할 폴더와 파일명이다. 3GB 정도 쓰기 가능한 폴더를 만들어주고 지정해주면 된다.

다음의 절차에서 이 파일을 참조하게 된다.

 

3. 이미지 읽어서 복구하기

 

위의 작업을 거쳐 wim 파일을 만들었으면, 아래처럼 명령 프롬프트에 써 준다.

dism.exe /online /cleanup-image /restorehealth /source:wim:d:\wim\install.wim:1

 

마지막의 1번은, 저 위에서 sourceIndex를 3번 하나만 택했기 때문에, 그 3번이 첫번째인 1번으로 등록되어 있어서 그렇다.

궁금하면, 아래의 명령으로 번호에 대한 정보를 확인할 수 있다.

dism.exe /Get-Wiminfo /Wimfile:d:\wim\install.wim

 

자체 파일을 보유하고 있지 않을 때, 미리 준비한 install.wim으로 복구하게 된다. 

이제 손상된 파일을 복구한다.

 

 

4. 마지막으로 sfc 

 

이제 마지막으로 명령 프롬프트에서,

sfc /scannow를 해준다.

 

그러면 끝.

 

 

참고 글

https://blasker.tistory.com/entry/%EC%9C%88%EB%8F%84%EC%9A%B010-ISO-%EC%9D%B4%EB%AF%B8%EC%A7%80%EC%9D%98-ESDElectronic-Software-Delivery%EB%A5%BC-WIMWindows-Imaging-Format%EC%9C%BC%EB%A1%9C-%EB%B3%80%ED%99%98-%EB%B0%A9%EB%B2%95-DISM%EC%9D%84-%EC%9D%B4%EC%9A%A9

 

https://www.wintips.org/how-to-extract-an-install-wim-file-that-contains-several-install-wim-files/

 

윈도우 원격 데스크톱으로 작업하다보면, 종종 호스트 컴퓨터의 인터넷 접속속도가 느려질 때가 있다. 그로 인해 호스트 컴퓨터의 화면이 부드럽게 넘어오지 못하는 등 여러가지 불편을 겪기도 한다.


랜카드의 설정을 바꾸어 이 문제를 해결해보자.



1. 문제 발생


내가 이용하는 환경은 호스트 컴퓨터와 클라이언트 컴퓨터 모두 KT의 500Mbps 플랜을 사용중이며, 양쪽 모두 4k 모니터를 사용한다.


이 플랜의 경우, 네트워크 속성에서 조회해보면 링크 속도(송신/수신)가 1000/1000 Mbps로 표시가 된다.

그런데, 원격접속시 종종 호스트 컴퓨터의 이더넷 접속속도가 10/10 Mbps로 떨어질 때가 있다. 원인은 잘 모르겠다.


일반적으로 사용하는 모니터가 1920 x 1080 해상도라고 할 때, 원격 데스크톱은 네 배 크기의 화면 이미지를 압축해서 보내주어야 하므로 대략 네 배 정도의 대역폭이 필요하다.(항상 화면의 모든 부분을 업데이트 하는 것 같지는 않으므로 아마도 네 배 보다는 적을 것이다)

정상적인 속도에서는 큰 불편함이 없지만 접속속도가 낮아지면 화면이 부드럽지 못해 여간 불편한 것이 아니다.


2. 간단하지만 말도 안되는 방법


호스트 컴퓨터의 이더넷 속성에서 "사용안함"을 하면 인터넷이 끊긴다.



그리고 아이콘이 회색(비활성화)으로 변해서 접속이 끊긴 것을 확인했으면 다시 "사용함"으로 바꾼다.


이 방법의 최대 단점은, 접속이 끊기는 순간 원격 데스크톱도 (당연히) 종료되고,

누군가 호스트 컴퓨터 앞에 앉아 "사용함"으로 바꾸기 전에는 다시 접속할 방법이 없다는 점이다.




3. 쉽게 할 수 있지만 매번 번거로운 해결 방법


이 때, 원격 접속 상태로 호스트 컴퓨터를 재부팅하면 된다.

죄를 지었으면 죄부팅을 해야겠지.

당연히 자동적으로 원격접속이 끊길 것이고, 호스트 컴퓨터가 재부팅 될 때 쯤 다시 원격 접속을 하면 링크 속도가 정상으로 되돌아간다.


단점은 사용하던 프로그램을 모두 닫아야 한다는 점.

그리고 재부팅 후 약간 뒤에 또 접속 속도가 떨어진다는 점

그리고 만에 하나, 재부팅하면서 그 순간에 호스트 컴퓨터의 IP가 변하면 다시 접속할 수가 없다.(이런 일은 거의 일어나지 않는다)


이런 재부팅이 귀찮았던 차에 혹시나 해서,

cmd 창에서 ipconfig /renew 등으로 해결을 시도 해보았지만 링크 속도는 변하지 않는다.


매번 이렇게 문제를 해결하다가 너무 소모적인지라, 맘먹고 이것 저것 시도해보고 찾던 도중 드디어 해결을 했다.



4. 쉽게 할 수 있고 영구적인 해결방법




호스트 컴퓨터의 랜카드 속성에서 <구성>을 클릭






랜카드마다 설정이 다르겠지만 위와 같은 비슷한 내용을 찾아본다.

"시스템이 절전 중인 동안 링크 속도를 줄입니다"를 해제




링크 속도에서 <속도 및 이중> 값은 기본이 "자동 설정"으로 되어 있을 것이다.

"이걸 1.0Gbps 전이중"으로 변경



문제가 해결되었다!





사실 둘 중의 하나 덕분인지 두 설정 모두 문제 해결에 기여했는지는 잘 모르겠다.

 하나씩 바꿔가면서 실험해보면 알겠지만, 귀찮으므로 여기서 끝.







-----------------------

2020-07-23 추가


글의 맨 밑에 여러가지 소프트웨어 성능을 비교한 링크를 첨부했습니다.

2019년에 TECHGAGE 에서 테스트를 했네요. 

이하, 2019년 2월에 작성한 원 글입니다.

----------------------------------



GL엔비디아의 쿼드로(Quadro)와 지포스(Geforce) 차이는 도대체 뭘까?


구글링 해봐도 잘못된 정보들도 많고 정확히 설명해주는 사람이 별로 없다. 유투브에는 경험적으로 비교한 영상만 볼 수 있다.

벤치마크도 몇개 나오는데, 벤치마크 역시 몇 가지 정해진 프로세스를 돌리는 것인지라 핵심을 짚지 못하는 것 같다.



보통 사람들이 알고 있는 점들은 다음과 같다.


"동일 가격대 기준으로 게임에서는 지포스가 빠르고 전문가용 그래픽 소프트웨어에서는 쿼드로가 빠르다"


분명 이 문장은 맞는 부분도 있지만 깔끔하게 모든 내용을 설명해주지는 못한다. 전문가용 그래픽 소프트웨어라도 엔비디아에서 별도의 드라이버를 지원해 주지 않는 어플리케이션은 쿼드로의 장점이 없다. 다수의 쿼드로 카드는 GTX에 비해 "소프트웨어적으로" 차별화 되어 있기 때문이다.

그렇다면 하드웨어는 같을까? 다수의 쿼드로 카드의 경우 거의 그렇다고 볼 수 있다.



카드를 구매하려는 입장에서 무엇을 사야 할까?



1. 게임을 주로 한다.


"지포스"


이건 이미 알고 있겠지만, 지포스 계열을 사면 된다. 


FP32 계산 유닛 Cuda Core 수가 중요하다.

정확한 표현으로 Cuda Core는 정수 연산 코어, 단정밀도(single precision, FP32), 배정밀도(FP64, double precision) 모두에 해당하지만

대부분의 경우 "쿠다 코어 수 3,584개"라고 하면 FP32 계산 유닛 수를 가리킨다.


GTX 1080 Ti 의 경우 3,584개이며, RTX 2080 Ti의 경우 4,352개다.


물론, VRAM도 관련이 없는건 아니지만, 게임 개발자는 그 시대에 생산되는 그래픽카드를 염두에 두고 개발하게 되므로 소비자의 입장에서 VRAM은 신경쓰지 않아도 된다. 



2. 영상 작업을 주로 한다.


"지포스" or "cpu"


자신이 사용하는 코덱이나 인코더가 OpenCL이나 Cuda 가속을 지원할 경우, 지포스 계열을 사면 된다.

만약 선호하는 코덱이나 인코더가 이 두가지를 지원하지 않는다면 cpu 성능에 의존하므로 cpu에 돈을 투자해야 한다.

쿼드로, 지포스 모두 쓸모가 없다는 말이다.



3. 포토샵 같은 2D 어플리케이션을 사용한다.


"지포스"


포토샵을 주로 사용한다면 지포스 계열을 사면 된다. 물론 쿼드로가 메모리 전송 속도가 다소 크긴 하지만 눈에 띄는 이점이 없다.


포토샵은 주로 cpu 성능에 의존하지만 여러가지 계산에서 점점 gpu를 이용한다. 어도비 공홈에서 어떤 명령어가 gpu 의 영향을 받는지 설명해주고 있다.

https://helpx.adobe.com/photoshop/kb/photoshop-cc-gpu-card-faq.html


이런 연산들은 대부분 FP32 연산이기 때문에 쿠다 코어 수가 중요하다. 쿼드로냐 지포스냐를 고민하지 말고 자금이 허락하는 안에서 쿠다 코어 수가 많은 것을 구입하면 된다. 같은 쿠다 코어 수 기준 쿼드로가 2배~ 7,8배 이상 비싸다


아래의 두 페이지를 비교해보면 쿼드로나 지포스나 별 차이 없다는 점을 알 수 있다. Intel HD 630 1GB가 두 벤치에 공통적으로 있으므로 참고하면 된다.

https://www.pugetsystems.com/labs/articles/Photoshop-CC-2017-NVIDIA-GeForce-GPU-Performance-899/

https://www.pugetsystems.com/labs/articles/Photoshop-CC-2017-NVIDIA-Quadro-GPU-Performance-900/


"3D가 아니면 그래픽카드에 투자할 필요 없다. cpu에 투자하라"는 옛 말이다. 점점 gpu 성능을 이용하는 명령어들이 많아지고 있다.



그리고, 

검색을 하다 보면 간혹 Quadro만 10bit 컬러를 지원하고 게임용카드인 Geforce는 8bit 컬러를 지원한다는 내용도 나온다.

그런데 이것은 분명히 잘못된 정보다.

10bit 컬러 포맷이라는건 채널당 10bit, 즉 R, G, B, A 각각 1024 단계의 색상을 사용한다는 것이고, 8 bit는 256단계의 색상을 사용한다는 말이다.

결국 이건 메모리를 어떻게 나누어 쓸 것인가에 대한 문제이므로 쿼드로/지포스와는 무관하다. 오히려 드라이버의 지원과 관계있다.

OpenGL이나 DirectX 등의 드라이버 수준의 단계에서는 카드 가리지 않고 10bit 모두 지원한다. 단, 포토샵 같은 어플리케이션이나 자체 이미지 포맷에서 몇 bit까지 제어할 수 있도록 지원하는가가 중요하다. (Adobe Lightroom 같은 어플리케이션에서 RAW 포맷을 지원하는 것 처럼)

그리고, 당연히 10bit 단계의 색상을 눈으로 모두 보려면 모니터가 이를 지원해야 한다.


참고로 DirectX는 잘 모르겠는데, OpenGL의 경우에는 채널당 10bit는 물론이고 무려 32bit 이미지 포맷을 텍스쳐와 이미지 모두 지원한다.

https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml

glTexImage2D라는 OpenGL명령어는 해당 명령어와 관련하여 다루게 될 이미지 포맷을 정의한다. 아래 표에서 GL_RGBA32F와 GL_RGBA32UI가 바로 128bit 이미지 포맷이다. (Red, Green, Blue, Alpha 각각 32bit)






4. 3D 어플리케이션을 사용한다.


"2019년 기준으로는 그래도 지포스!!!!!"

"Cuda Core 가 몇개를 확인하고 살 것. 코어 수에 성능이 비례한다고 보면 된다"


캐드나 3dsMax, Rhino3D 등 특정 어플리케이션을 주로 쓴다면, 자신이 사용하는 어플리케이션이 Quadro의 지원을 받는지 검색 등으로 찾아보자. 지원받지 않는다면 똑같다. 메모리 대역폭 말고 칩이 근본적으로 같기 때문이다. (Quadro P6000 와 GTX 1080 Ti 의 경우).

그리고 아마도, 차별점을 찾기 어려울 것이다. 적어도 2019년 현재로서는.


과거에, 그러니까 예를 들어 2003년 정도 기준으로 설명하자면 분명히 두 라인업의 하드웨어 차이가 존재했다.

여기를 한번 보자.

https://www.techpowerup.com/gpu-specs/nvidia-nv35.g18

NV35 칩을 사용한 Geforce FX 5900 Ultra와 Quadro FX3000G를 비교해보자. 페이지 하단의 표를 살펴보면 쿼드로의 경우 NV35 GL 이라는 다소 이형의 칩을 사용하였다는 점을 알 수 있고 ROPs 가 8개 지포스의 두배다. ROP는 Rendering OutPut unit의 약자로서, OpenGL 그래픽 파이프라인의 마지막 단계에서 화면에 뿌려주는 프래그먼트 셰이더와 관련된다. NV35GL 칩은 이 ROP를 지포스에 비해 두배 보유함으로서 양면 렌더링이나 더 많은 샘플링을 이용한 안티에일리어싱을 하드웨어적으로 지원할 수 있었던 것 같다. 픽셀 처리 성능이 두배이므로 대략적으로 말이 된다.

당시의 두 라인업 비교 공식 문서는 다음의 pdf를 참고하자.

http://www.nvidia.com/object/quadro_geforce.html


이러한 하드웨어 차이로 인해, 엔비디아는 뷰포트 드로잉 가속 기술에 대한 OpenGL 확장 명령어를, 특정 소프트웨어에 대한 별도의 쿼드로 드라이버에서만 지원했었다. 이러한 기술 지원 정책이 있었던 탓에 하드웨어의 전반적인 성능이 낮았던 과거에는 쿼드로에 돈을 투자할 만한 가치가 있었지만, 요새는 약간 달라진 것 같다.


일단 하드웨어의 차이가 없다. Quadro P6000과 GTX 1080 Ti를 놓고 보면 똑같은 GP102 칩셋을 사용한다. 

https://www.techpowerup.com/gpu-specs/nvidia-gp102.g798

칩셋 크기는 똑같은데 내부의 SM을 모두 활용하느냐, 아니면 몇 개를 사용하지 않느냐에 따른 SM 유닛 개수 차이로 인해 쿠다 코어 및 전반적으로 쿼드로측이 약간 우세하지만(3840 vs 3584), 딱 그 뿐이며 지원 명령어는 차이가 없는 것 같다.

그래서 예를 들어 "autocad performance quadro vs geforce" 와 같이 특정 어플리케이션에 대해 검색해보면, 사용자들이 두 카드를 비교해놓은 결과를 볼 수 있는데 "과거에는 차이가 있었지만 최근에는 차이가 없다"라는 것이 중론이다. 


심지어 어떤 사람들은, "차이가 없는데, 이것에 대해 언급하는 것이 금기시 되어 있는 것 같다"라고도 써 놓았다. 엔비디아 공식 홈페이지에서는 정보를 찾기 어렵기 때문이다. (https://forums.autodesk.com/t5/autocad-architecture-forum/graphics-card-debate-geforce-vs-quadro/td-p/5568485)


그렇게 볼 때, GTX 1080Ti 같은 고가의 지포스 카드는 충분히 메리트가 있다.

같은 GP102 칩을 사용한 Quadro P6000 과 비교할 때 GTX 1080Ti는 엔비디아 공홈 기준 가격이 7배 정도 차이나기 때문이다. 

게다가 예를 들어 Rhino3D Vray의 실시간 뷰포트 RT 렌더링같은 경우 Cuda 코어를 사용해 연산하기 때문에 쿠다코어 수가 많은 카드를 사는 것이 절대적으로 유리하다.


만약 당신이 큰 회사의 컴퓨터 담당자고, 단지 몇 대에 한하여 PC를 구성해야 한다면 그냥 고민없이 쿼드로를 구입하면 된다. 몇 백만원 아꼈다고 칭찬받을 일 없다. 


스스로의 컴퓨터를 구성한다고 지포스를 구매하길 권장한다. 쿼드로가 성능은 근소하게 앞서지만 고가의 지포스 계열도 꽤 괜찮은 성능을 제공하기 때문이다. 동일 가격대라면 두 말할 필요도 없다.

이 링크를 한번 보자. https://www.youtube.com/watch?v=JtX5o-MlyaU

2016년 당시 비슷한 가격대인, 구형 쿼드로와 신형 지포스를 비교했다.


보통의 학생이라면 무조건 지포스를 추천한다.




5. WebGL이나 VR 등을 즐긴다.


"지포스"


동일 가격 기준으로 할 때, 무조건 GTX다. 


이 경우도 결국 FP32 cuda 코어 수가 중요하다.

두 카드 모두 가지고 있을 경우 http://david.li/fluid/ 등에서 테스트해보면 된다.




6. 배정밀도(FP64) 계산을 주로 한다.


"다른 기준으로 보자"


Geforce 나 Quadro의 기준으로 보지말고 gpu의 칩이 무엇인지 확인해야 한다.


사실, 이쯤 되면 당신은 아마도 이 글을 참고하지 않고 스스로 GPU chip 다이어그램을 보고 판단할 수 있을 것 같다.

GPU 설계의 기본 단위인 SM을 보면, 정수연산 유닛, 단정밀도 유닛, 배정밀도 유닛이 몇개 있는지 알 수 있다.


Volta Architecture의 GV100 칩을 사용한 Quadro GV100이나 Titan V 같은 경우 FP64 연산 유닛과 FP32 유닛이 1:2의 비율로 들어가 있다. Pascal Architecture의 GP100칩을 사용한 Quadro GP100 이나 Tesla P100의 경우도 역시 1:2의 비율이다. 배정밀도 성능이 단정밀도의 1/2까지 올라간다.


참고로 GP102를 사용한 Quadro P6000이나 GTX 1080Ti는 똑같이 FP64 유닛이 매우 적다. 계산성능이 단정밀도의 1/32에 불과하다.


아래 페이지를 참고해보자.

https://www.microway.com/knowledge-center-articles/comparison-of-nvidia-geforce-gpus-and-nvidia-tesla-gpus/




7. 딥러닝을 한다.


"RTX"


어차피 cuda core로 계산을 돌릴 것이기 때문에 쿼드로는 별다른 이점이 없다.

만약 11GB가 넘는 데이터를 한번에 올려놓고 계산을 돌려야만 한다면 24GB를 지원하는 쿼드로 카드를 사면 된다.(이런 경우가 있는지는 잘 모르겠다)

(나는 딥러닝은 직접 해보지 않았다. 단지 기존의 지식을 바탕으로 몇 가지 글을 읽은 결론이니 참고로만 하자)


딥러닝의 경우 배정밀도 계산은 거의 쓰이지 않고 반 정밀도(FP16) 계산으로도 충분하다고 한다. 

그래서 지포스 GTX 1080 Ti 를 사람들이 많이 사용하고 있었다.


이에 따라 엔비디아에서는 딥러닝에 주로 쓰이는 반정밀도 4x4 행렬 연산을 하드웨어에서 지원하는 Tensor Core를 개발해서 RTX 카드에 사용했다. 다음을 참고하자.

https://devblogs.nvidia.com/nvidia-turing-architecture-in-depth/


쿼드로나 지포스의 비교 관점으로 보지 말고, 새로운 Turing Architecture 가 적용된 카드를 사면 된다.

지포스라면 RTX 2080 Ti가 있겠다. 



8. 서버에 다수의 컴퓨터를 구성한 후 VGA를 꽂아서 성능을 극대화하고자 한다.


"QUADRO"


Quadro가 좋다.

RDMA 방식을 사용하여 서로 다른 컴퓨터의 카드 간에 데이터를 복사할 때 cpu를 거치지 않고 VRAM 에서 곧바로 VRAM으로 가는지 확인해보면 된다.


컴퓨터 한 대 안의 멀티 VGA의 경우 쿼드로의 장점이 없지만, 컴퓨터가 여러대라면 쿼드로가 확실한 우위를 가진다.

사실 이 경우도 이런 글을 참고로 하지 않고 좀 더 전문적인 지원을 받을 것이라 생각한다.

여기에 기본적인 설명이 있다.

https://developer.nvidia.com/gpudirect













이번에는 두 라인업의 차이를 비교해서 몇 가지 적어보았다

 

내용은 위와 약간 중복되지만 다른 관점에서 서술한 글임을 참고하자.

1번부터 5번은 지포스 GTX 1080 Ti와 QUADRO P6000을 염두에 두고 썼다.


1. 기본 설계가 같다. 쿠다 코어 수가 같다.


두 카드 모두 Pascal Architecture다. SM구조가 동일하다. 

FP32 쿠다 코어 수가 3,584개로 같다. FP32 쿠다 코어는 GPU연산의 핵심이다.


2. VRAM은 다르다.


1080Ti 는 11기가, P6000은 24GB로 쿼드로가 두 배 이상이다.

쿼드로는 ECC램을 사용한다는 정보도 있다. 

램에 있어서는 분명히 쿼드로가 좋다. 더 많은 데이터를 GPU 램에 올려놓고 작업할 수 있다. VRAM이 절대적으로 아쉬운 사람은 쿼드로를 구입해야 한다. host ram(본체 메모리)에서 device ram(VGA 메모리)으로 자주 복사하는 작업은 상대적으로 시간비용이 많이 들고, 램 자체도 gpu 쪽이 빠르다.

그렇지만 가격이 네 배 이상 차이난다는 점을 항상 잊지 말자.


3. 쿼드로는 윈도우 원격 데스크톱 접속시 OpenGL 실행이 가능하다.


지포스 계열은 windows RDP 접속시 OpenGL 실행이 안된다. 물론 매번 불편하지만 이걸 극복하는 방법도 있다. ( steelblue.tistory.com/10 )

쿼드로는 된다. 엔비디아에서 고의적으로 지포스를 막은 것 같다. 



4. 때문에 GTX를 쿼드로로 인식시켜(hacking) 사용하는 사람들도 있었다.


이를테면 아래와 같은 사례

https://thetechjournal.com/electronics/computer/hardware/convert-gtx-690-into-tesla-k10-or-quadro-k5000-with-a-simple-hack.xhtml


즉, 하드웨어의 근본이 크게 다르지 않기 때문에, 저항을 조작하여 훨씬 저렴한 지포스를 쿼드로로 인식시켜 드라이버를 깔고 사용하는 사례들도 10년 전부터 있었다.



5. WebGL을 사용하는 웹페이지에서 저가의 Quadro는 극악의 성능을 보여준다.


예를 들어 쿼드로 P620 같은 경우 파스칼 아키텍쳐로서, 램 2기가에 쿠다코어 512개다.

한물 간 지금은 다나와 최저가로 22만원인데, 한창때 26만원이었다.


그런데, 13만원 정도의  GTX 1050 의 쿠다코어도 640개다.

쿠다 코어 수는 gpu 연산의 핵심이다. 예를 들어 http://david.li/fluid/ 같은 사이트에 접속해서 두 카드로 시뮬레이션 해 보면 쿼드로가 상대적으로 느린 것을 육안으로 확인할 수 있다.


6. 마찬가지로, Cuda 코어 수가 핵심인 GPU 연산에서 동일 가격대의 지포스는 QUADRO 보다 절대적 우위에 있다.


쿼드로 계열의 고가 가격정책 때문에 100만원의 예산으로 그래픽 카드를 살 때, 지포스는 GTX 1080 Ti를 살 수 있고 쿼드로는 P4000 정도를 살 수 있다. 쿠다코어는 GTX가 딱 두 배 많다.(3584 vs 1792) 게임에서나, GPU 연산을 필요로 하는 분야에서나 당연히 GTX를 사야 한다. 딥러닝 연구자들은 이런 점을 알기 때문에 GTX 1080Ti나 RTX 2080 Ti를 찾는다.



7. 엔비디아가 쿼드로 페이지에서 강조하는 OpenGL 확장은 지포스도 지원한다!!


그렇다면, VRAM용량을 제외하고 쿼드로가 차별화된 점은 과연 무엇인가?

세세한 하드웨어적 차이점은 잘 모르겠다. 좀 더 고가의 안정적인 부품을 썼을 수도 있고, 잘 뽑힌 칩을 우선적으로 배정했을 수도 있다.


확실한 부분은 소프트웨어적으로 쿼드로만 지원하는 경우가 있긴 있다는 점이다. 

엔비디아 자체적으로 지원하는 OpenGL 확장 명령어의 경우, 몇 가지 조회해보면 쿼드로만 지원하는 경우가 있다.

http://developer.download.nvidia.com/opengl/specs/WGL_NV_video_out.txt

지포스 계열에서는 이 기능을 구현하는 드라이버가 깔리지 않아 아예 사용할 수 없다.


그런데 엔비디아에서 복잡한 오브젝트를 디스플레이하기 위해 구현하는 핵심 기술들의 경우에는 지포스도 지원한다.

간단히 말해, 많은 오브젝트를 그렸을 때 쿼드로나 지포스나 똑같이 팽팽 돌아간다는 말이다.

이를 테면 Bindless Graphics처럼 cpu의 drawcall을 최소화 해서 gpu 상에서만 처리되도록 하는 기술은 아래에 샘플 코드가 있다. 

RTX 기술인 메쉬 셰이더와 bindless 기술들이 모두 들어가있다.

https://github.com/nvpro-samples/gl_vk_meshlet_cadscene

여기서 설명을 보면 쿼드로의 벤치마크만 있지만, 해당 OpenGL 확장들은 지포스 드라이버에서도 지원한다.

예를 들어 오토캐드 개발자들이 OpenGL로 개발을 할 때 해당 명령어를 사용하여 뷰포트 렌더링 구현을 한다면 그대로 실행될 수 밖에 없다. 지포스도 똑같이 빠르다는거다.


참고로 bindless graphics 에 대해 부연하자면,  ( https://www.nvidia.com/object/bindless_graphics.html )

OpenGL로 코드를 작성할 때, 1초에 60프레임을 그린다면, 매 프레임마다 cpu에서 gpu로 명령을 내려서 그린다. 

이것을 어떤 방식으로 그리느냐에 따라서 그리기 속도가 굉장히 차이가 많이 난다. 

예를 들어 백만개의 삼각형을 그릴 때, cpu에서 백만번의 drawcall을 gpu로 보낸다고 생각하면 어마어마하게 느리다. 1초에 1프레임도 안나올 것 같다.

그래서 보통은 삼각형을 그룹지어서 drawcall 하거나, 좌표와 인덱스를 미리 vram으로 보낸 뒤에 한번의 drawcall로 그리기도 한다. 


이 때 cpu에서 drawcall을 보낼 때 사용하는 트리거 역할의 변수와 vram에 저장되어 있는 데이터의 주소를 binding 한다고 표현하는데, bindless라는건 gpu의 vram 주소들 목록에 (바인딩 없이)직접 엑세스 해서 drawcall 할 때 cpu와 gpu 사이에 왔다갔다 하는 작업을 최소화 하자는 거다. 

텍스쳐 매핑의 경우에도 구현하는 명령어가 있다.


더불어,

2018년에 엔비디아에서 새로 출시한 RTX 카드의 경우에는 새로운 튜링 아키텍쳐의 적용으로 OpenGL에서 Mesh Shader 를 사용할 수 있게 되었다. 이게 무엇인고 하니, 기존의 OpenGL 파이프라인은 버텍스 셰이더부터 프래그먼트 셰이더까지 거치는 동안 모든 데이터들이 고정된 함수들을 나란히 통과해야 했기 때문에, 불규칙한 형상에서 다른 복잡도의 데이터들이 전송되어 병렬 처리 작업을 할 때 복잡한 쪽의 시간에 맞추어진다는 단점이 있었다. 그런데 튜링 아키텍쳐의 Mesh Shader는 Task Shader와 더불어 기존의 버텍스 셰이더, 테셀레이션 세이더, 지오메트리 셰이더 등 버텍스 처리 부분을 대체시키고, 한쪽의 작업이 끝나면 다른 쪽의 작업을 할당하도록 상호 유연하게 협력하도록 실행된다. 


이 메쉬 셰이더의 기본적인 특징과 더불어 컬링이나 버텍스 재사용 등 다른 알고리즘을 결합시켜, 로딩된 메쉬들을 확대할 경우 기존 방식보다 프레임이 두배 혹은 그 이상 향상된다. 엄청난 성과다.

이것 역시 당연히 모든 RTX 계열(지포스와 쿼드로 포함)에서 해당 코드를 실행할 수 있다. 지포스나 쿼드로 마찬가지다. 튜링 아키텍쳐 칩이라면 가능하다.





8. 물론 특별하게 차별화된 QUADRO도 있다. 그런데 이건 지포스 vs 쿼드로의 관점이 아니다.


Volta Architecture의 경우 배정밀도(FP64, double precision)의 코어가 FP32의 절반이나 들어가 있다. 

따라서, 볼타 아키텍쳐로 제작된 Tesla V100, Quadro GV100의 배정밀도 부동소수점 연산 능력은 같은 세대의 GTX나 일반적인 Quadro 보다 10배 이상 높다. 

Quadro GP100 이나 Tesla P100 은 GTX 1080 Ti 와 동일한 Pascal architecture 계열이지만 FP64 계산능력은 역시 10배 이상 높다. 동일 세대지만, GTX1080Ti 나 Quadro P6000 은 FP64 cuda core수가 현저히 적은 GP102 칩을 썼고, Tesla P100이나 Quadro GP100은 FP64 Cuda Core가 FP32의 절반까지 들어간 GP100 칩을 사용했기 때문이다.


따라서 FP64 연산 능력이 절실한 사람들은 쿼드로나 테슬라 카드를 구입해야 한다.


아래에 연산능력 비교 참조

https://www.microway.com/knowledge-center-articles/comparison-of-nvidia-geforce-gpus-and-nvidia-tesla-gpus/




9. 그럼 무엇을 살까? 


그래픽 작업을 하는 일반적인 경우라면 쿼드로 말고 그냥 GTX나 RTX를 사기 바란다.

배정밀도 연산을 필요로 하는 사람이라면 Volta Architecture 등 스스로 찾아서 특별한 카드를 구매하면 된다.


같은 architecture라고 가정했을 때, 쿼드로의 장점은 어디까지나 몇개의 한정된 3d용 응용 소프트웨어의 작업화면 상에서의 실시간 디스플레이까지다. 

렌더링 성능은 cpu나 쿠다코어 수에 의해 좌우된다.


30만원 정도의 GTX 1060 의 경우에도 과거에 비해 디스플레이 성능이 매우 높아졌기 때문에 웬만큼 복잡한 화면은 견뎌낸다. 


같은 예산으로 컴퓨터를 맞춘다고 할 때, 게임을 전혀 안하더라도, 점점 높은 쿠다코어를 활용하는 경우가 많아지기 때문에 동일 가격대의 쿠다코어가 현저히 적은 쿼드로 계열을 사는 것은 추천하고 싶지 않다. 예를 들어 영상 인코딩 시 OpenCL을 사용하거나 WebGL 페이지를 보거나 하는 경우다.


요새는 이 실시간 디스플레이도, 예를 들어 vray의 경우 GPU연산을 이용하여 레이트레이싱 결과물을 뽑아주는 경우도 있는데, 이것은 위에서 서술한 쿼드로 지원과 또 다른 얘기다. 순전히 쿠다코어 연산에 의존하기 때문에 쿼드로의 이점이 전혀 없다고 보면 된다.




일부는 직접 해보면서, 일부는 글들을 찾아보면서 썼습니다.

혹시라도 글에 잘못된 부분이 있을 경우, 댓글로 달아주시면 감사드리겠습니다.




---------------------------------------------------------------------------------



2020.05.19 추가


댓글에 카티아와 솔리드웍스에 쿼드로가 강점을 보인다는 언급이 있어, 조금 더 찾아보았습니다.


https://www.engineering.com/DesignSoftware/DesignSoftwareArticles/ArticleID/18630/Whats-the-Difference-Between-GeForce-and-Quadro-Graphics-Cards.aspx


위의 글을 보면, 카티아, 솔리드웍스, 그리고 특히 지멘스NX에서 쿼드로가 높은 성능을 보여주네요.

위의 글에서도 쿼드로와 지포스의 아키텍쳐가 'exactly same'이라고 했습니다. 다만, 보다 많은 메모리 등 차이가 없는 것은 아니라고 하는데요, 지멘스NX는 한번도 써본적이 없어서 어떤 환경에서 어떻게 테스트 했는지는 잘 모르겠습니다.



아래와 같은 비교 영상에서는 솔리드 웍스에서 지포스와 쿼드로의 차이가 없습니다.



어느 정도의 부하가 걸리느냐에 따라 결과가 달라질 것 같네요. 쿠다 코어 수가 같을 때 쿼드로의 메모리가 더 많기 때문에, 많은 오브젝트들을 올리면 당연히 성능차이가 날 것 같습니다. 


위의 글에서도 설명했지만, 쿼드로와 지포스가 '동일하다'는 것이 아닙니다.

당연히 예산이 충분히 있으면 메모리도 충분하고 테스트로 보증되어 있는 쿼드로를 구입하시면 됩니다.


다만, 같은 예산에서 쿠다코어 수가 적은 쿼드로를 구입하는 것보다는 쿠다코어 수가 몇 배는 많은 지포스를 구입하라는 것이 이 글에서 가장 중요한 부분이기도 합니다. 

현명한 선택 하시기 바랍니다.




-------------------------------------

2020-07-23 추가


아래의 링크에서 포토샵, 마야, 지멘스NX, 카티아 등 많은 프로그램에 대해서 테스트를 해 놓았습니다.


https://techgage.com/article/nvidia-quadro-rtx-4000-review/


많은 분들이 경험으로 언급해주신 것처럼 지멘스NX나 카티아의 경우에는 쿼드로의 성능이 우월합니다.

마야, 3dsmax 는 그렇지 않고요.


영어에 익숙치 않으시더라도 그래프 보는 것은 어렵지 않으리라 생각합니다.









윈도우 원격 데스크톱으로 A 컴퓨터에 접속해서 A 컴퓨터의 네이버 클라우드 탐색기를 실행시키려고 하면 "pc를 재시작하라"는 창이 뜬다. pc를 재시작해도 마찬가지다. 


해결방법은 간단하다.

관리자모드로 실행시키면 된다.


실행 파일은 일반적인 경우 다음의 경로에 있다.


C:\Program Files\naver\NaverNDrive


여기서 NDrive.exe 를 우클릭, 관리자 권한으로 실행하면 끝.

2020.08.10 내용 업데이트


엔비디아에서 지포스계열의 윈도우 RDP실행시 opengl 지원 프로그램을 지난 4월부터 배포하기 시작했다. 

즉, 아래 내용 다 필요없고 엔비디아 홈피에서 해당 프로그램을 받으면 된다.


아래에 설명이 있다.

https://www.opengl.org/news/comments/nvidia-provides-opengl-accelerated-remote-desktop-for-geforce


VGA 드라이버는 440 버젼 이후이면 되고

호스트가 되는 컴퓨터에서 위의 링크에서 다시 링크로 걸어준 프로그램을 내려받아 실행시킨 후 재부팅 한번 해주면 된다.


그러면 그 다음에 rdp로 접속하는 컴퓨터에서 아래처럼 복잡한 절차 없이 opengl 프로그램을 실행시킬 수 있다.


이렇게 간단한걸, 진작에 좀 해주지.


프로그램을 다운받으려면 엔비디아 계정이 있어야 하기 때문에 좀 귀찮다. 용량이 매우 적으므로 여기 직접 첨부해놓았다.


nvidiaopenglrdp.zip



끝.




----------------------------------------------------------------------------------------------



코딩을 하다보면 성능이 좋고 데이터가 저장되어 있는 PC를 서버로 두고, 외부에서 클라이언트로 접속해 서버 컴퓨터의 코드를 실행시켜야 할 경우가 있다. 물론 데이터의 용량이 작고 구동이 가벼울 경우 온전히 복사하거나 클라우드 동기화를 통해 직접 눈 앞에 있는 컴퓨터로 실행시키면 그만이지만, 그렇지 못한 경우도 있다.


예를 들어 몇기가의 데이터를 읽어서 OpenGL로 구동시켜야 할 경우에는 클라우드 동기화보다는 원격 접속이 편하다. 


그런데 문제가 있다. 윈도우 원격 데스크톱을 활용한 원격 접속의 경우에는 OpenGL이 1.1 버젼까지만 구동가능하므로 대부분 에러를 내뱉고 실행되지 않는다.



해결 방법은 여러가지가 있다.


1. windows RDP 대신 다른 원격 접속 프로그램을 사용한다. (어떤 것에서 OpenGL이 실행 되는지는 확인하지 못했다)


2. 엔비디아 vga 기준으로 할 때, Quadro 계열을 구입한다.


엔비디아에서는 GTX나 RTX 계열의 vga를 꽂은 PC에 원격 접속을 할 때, OpenGL의 사용을 막아놓았다. 그런데 쿼드로 계열은 된다. 당연히 소프트웨어적으로 막아놓은 것이라 엔비디아에서 풀어주면 되는데 그렇게 하지 않는다. 다른 어떤 이유가 있는지는 모르겠지만 여하튼 지원하지 않는다.


그렇지만 cuda core 기준으로 볼 때, 같은 쿠다코어 수의 vga를 구입하려면 가격이 다섯배 이상 뛰므로 추천하지 않는다.



3. 그래서 해결방법은 다음과 같다. 


요약해서 말하자면 원격 접속을 끊고, 기본 계정 상태에서 코드를 실행시킨 뒤 다시 원격 접속하는 방법이다. 그러면 OpenGL 창이 떠 있을 것이다!!!


그러면 그걸 어떻게 할까?


아래의 코드로 .bat 파일을 만들어 "관리자 모드"로 실행하면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@echo off
echo.
echo Remote Desktop will be temporarily disconnected . . . please reconnect after a few seconds.
echo.
pause
@echo on
REM The active session has an arrow as the first character
setlocal EnableDelayedExpansion
FOR /F %%A in ('qwinsta'do (
    set tempSessionName=%%A
    if "!tempSessionName:~0,1!"==">"  ( 
        @echo on
        tscon.exe !tempSessionName:~1! //dest:console 
        @echo off
    )    
)
@echo off
echo.
@echo on
rundll32.exe user32.dll, LockWorkStation
@echo off
echo.
echo Starting MyProgram.exe . . .
@echo on
REM 여기서 컴파일된 코드를 실행시킨다.
D:\user_folder\folder1\.execution.exe
@echo off
echo.
pause
cs


OpenGL 코드를 작성할 정도면 그 밖의 궁금한 부분은 스스로 해결 할 수 있을 것이라 생각한다.

예를 들어 실행했을 때, dll을 못찾는다거나 등등의 부분은 bat 파일에서 exe를 실행시키기 전에 디렉토리를 변경하거나 필요한 부분을 path에 등록하는 방식 등으로 해결할 수 있다.



*.

처음에 원격 접속으로 OpenGL 실행이 되지 않았을 때 의구심이 들었던 부분이 있었다.

코드와 데이터가 있는 PC에서 opengl 코드를 실행시켜 OpenGL이 작동하는 창을 띄운 뒤, 옆의 아무 PC로 가서 원격접속을 해보았더니 창이 그대로 떠 있고 OpenGL도 문제없이 구동되었었다. 그렇지만 원격접속 상태에서 창을 닫은 후 다시 실행하려면 되지 않았다. 즉, 원격 접속 상태에서 아예 불가능한게 아니라 처음 구동시킬 때의 계정이 원격접속 계정이면 안되게 막아놓았다는 점을 알 수 있었다.


*.

아래 질문의 답변에서 힌트를 찾았고, 몇 군데 더 참고해서 위의 글을 작성하였다.

https://stackoverflow.com/questions/41833949/opengl-and-remote-desktop



d3.js 의 force layout은 네트워크 다이어그램을 볼 수 있는 강력한 툴이지만, 점의 갯수가 많아질 때 점과 선들이 한데 뭉쳐서 알아보기 힘들다는 단점이 있다. 이러한 단점을 해결하기 위해 여기서는 force layout을 확대축소할 수 있도록 코드를 수정하는 방법을 설명하겠다. force layout을 다루는 기본적인 방법은 알고 있다고 전제하였다.

 

 

 

다음은 d3.js 의 force layout의 샘플과 소스코드다.

소스코드 원본에서  json을 불러오는 부분만 수정한 것이다. 원본은 여기에 있다.

기본적으로 점들의 drag 기능을 제공한다.


(바로 아래의 움직이는 force layout을 보려면 크롬의 경우에는 주소창 우측에서 '안전하지 않은 스크립트 로드'를 눌러야 한다)

 

 

 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!DOCTYPE html>
<meta charset="utf-8">
<head>
 
</head>
 
<body>
<SCRIPT src="http://d3js.org/d3.v3.min.js"></SCRIPT>
 
<SCRIPT>
 
     var graph = {
        "nodes": [
          { "name": "Myriel", "group": 1 },
          { "name": "Napoleon", "group": 1 },
          // 중간 생략
          { "name": "Mme.Hucheloup", "group": 8 }
        ],
        "links": [
          { "source": 1, "target": 0, "value": 1 },
          { "source": 2, "target": 0, "value": 8 },
        // 중간 생략
          { "source": 76, "target": 58, "value": 1 }
        ]
    };
    var width = 640,
        height = 400;
 
    var color = d3.scale.category20();
 
    var force = d3.layout.force()
        .charge(-120)
        .linkDistance(30)
        .size([width, height]);
 
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
 
    
        force
            .nodes(graph.nodes)
            .links(graph.links)
            .start();
 
        var link = svg.selectAll(".link")
            .data(graph.links)
          .enter().append("line")
            .attr("class", "link")
            .style("stroke-width", function (d) { return Math.sqrt(d.value); });
 
        var node = svg.selectAll(".node")
            .data(graph.nodes)
          .enter().append("circle")
            .attr("class", "node")
            .attr("r", 5)
            .style("fill", function (d) { return color(d.group); })
            .call(force.drag);
 
        node.append("title")
            .text(function (d) { return d.name; });
 
        force.on("tick", function () {
            link.attr("x1", function (d) { return d.source.x; })
                .attr("y1", function (d) { return d.source.y; })
                .attr("x2", function (d) { return d.target.x; })
                .attr("y2", function (d) { return d.target.y; });
 
            node.attr("cx", function (d) { return d.x; })
                .attr("cy", function (d) { return d.y; });
        });
    
 
</SCRIPT>
</body>
cs



우선 기본적인 zoom을 위해 몇가지 필요한 부분들을 추가하고 수정해야 한다. 우선 본격적으로 force layout에 대한 코드를 작성하기 이전에 zoom에 대한 부분을 추가한다. var color =.....의 밑줄에 넣어주면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 // scale이 적용되는 공간 정의
    var xScale = d3.scale.linear()
            .domain([0, width])
            .range([0, width]);
    var yScale = d3.scale.linear()
            .domain([0, height])
            .range([0, height]);
 
    //zoom 기능 정의. scaleExtent 부분을 수정하여 zoom의 한계를 조정할 수 있다.
    var zoomer = d3.behavior.zoom().x(xScale).y(yScale).scaleExtent([0.18])
                      .on("zoom", zoom);
 
    //위에서 호출한 zoom 함수를 정의.
    //혹시 모를 나중을 위해 곧바로 tick()을 호출하지 않고, zoom 함수를 한번 더 거쳤다.
    function zoom() {        
        tick(); 
    };
cs




svg 공간을 정의한 바로 뒷부분에 앞에서 정의한 zoomer기능을 호출해둔다.


1
2
3
4
5
6
7
    //기존에 있던 부분
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
 
    // 이부분을 추가한다.
    svg.call(zoomer);
cs



tick 함수를 수정한다. 기존 코드에서는 force.on에서 tick을 바로 정의하고 있었지만, 함수 호출을 위해 별도로 분리시켜준다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//기존 코드의 force.on 부분을 수정해서 tick 함수를 정의한다.
    force.on("tick",tick);
 
    function tick(){            
            // link 부분 좌표들 바깥으로 scale 함수들을 덮어씌운다.
            link.attr("x1"function (d) { return  xScale(d.source.x); })
                .attr("y1"function (d) { return yScale(d.source.y);  })
                .attr("x2"function (d) { return xScale(d.target.x); })
                .attr("y2"function (d) { return yScale(d.target.y); });
            
           //node는 svg 문법의 규칙 따라 transform으로 바꾸어 주어야 한다.
            node.attr("transform"function (d) {
                return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")";
            });
        };
 
cs


이제 아래와 같이 zoom 과 pan이 가능해졌다. 이제 node들이 뭉쳐있는 곳을 확대해서 볼 수 있다.

 

 

그런데 문제가 있다. 점을 drag해보면 상당히 부자연스럽게 이동한다. drag할 때 node의 위치를 계산하게 되는데, zoom에 의한 xScale과 yScale 변화가 drag 부분에서 계산되지 않아서 발생하는 현상이다. 이 문제를 해결하기 위해 force에서 기본으로 제공하는 drag함수를 호출하지 않고 drag 함수를 재정의 하여 사용해야 한다. 위에서 zoom을 정의해준 부분 밑에 아래의 코드를 추가한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
   
   //drag 함수를 새로 정의한다.
   var drag = d3.behavior.drag()
            .origin(function (d) { return d; }) //
            .on("dragstart", dragstarted)
            .on("drag", dragged)
            .on("dragend", dragended);
 
    // 드래그가 시작될 경우.
    function dragstarted(d) {
        d3.event.sourceEvent.stopPropagation();  //다른 이벤트 전달 중지
        d.fixed |= 2
        //d3.js 오리지널 소스의 force.drag에서 참고함.
        //드래그하는 점의 진동이 발생하지 않도록 임시로 fix 한다.
    }
 
   //드래그 되는 동안.
    function dragged(d) {
 
        //마우스의 위치를 잡아낸 뒤, 
        //invert 계산을 거쳐 zoom이 없을 경우의 x,y 스케일을 알아냄
        //zoom 이 포함된 좌표를 계산하는 것은 tick()의 역할임.
        var mouse = d3.mouse(svg.node());
        d.x = xScale.invert(mouse[0]);
        d.y = yScale.invert(mouse[1]);
 
        // 앞에서 임시로 fix해준 점의 변위 (px, py)를 직접 입력해 줌
        d.px = d.x; .
        d.py = d.y;
        force.resume();  // force layout이 움직이도록 resume함.
    }
    
    //drag가 끝난 후.
    function dragended(d) {       
        d.fixed &= ~6
        //d3 오리지널 소스의 force.drag에서 참고함. 
        // 앞에서 fix해준 점을 다시 풀어줌        
    }
 
cs



새로 정의된 drag 함수를 호출한다. node 변수 끝부분의 force.drag 부분을 아래와 같이 수정한다.


1
2
3
4
5
6
7
8
     var node = svg.selectAll(".node")
            .data(graph.nodes)
            .enter().append("circle")
            .attr("class""node")
            .attr("r"5)
            .style("fill"function (d) { return color(d.group); })
            .call(drag);     // 바로 이 부분을 수정한다.
 
cs

이제 필요한 부분을 모두 수정하였다. force layout의 zoom과 pan, 그리고 점의 드래그까지 완벽하게 동작할 것이다. 최종 수정된 force layout과 소스는 아래에 덧붙여두었다.

 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<SCRIPT>
 
    var graph = {
        "nodes": [
          { "name""Myriel""group"1 },
          { "name""Napoleon""group"1 },
          // 중간 생략
          { "name""Mme.Hucheloup""group"8 }
        ],
        "links": [
          { "source"1"target"0"value"1 },
          { "source"2"target"0"value"8 },
        // 중간 생략
          { "source"76"target"58"value"1 }
        ]
    };
    var width = 640,
        height = 400;
     var color = d3.scale.category20();
 
 
 
    var xScale = d3.scale.linear()
            .domain([0, width])
             .range([0, width]);
 
    var yScale = d3.scale.linear()
        .domain([0, height])
       .range([0, height]);
    var zoomer = d3.behavior.zoom().x(xScale).y(yScale).scaleExtent([0.18]).on("zoom", zoom);
    function zoom() {
       
        tick(); 
    };
 
    var drag = d3.behavior.drag()
            .origin(function (d) { return d; })
             .on("dragstart", dragstarted)
            .on("drag", dragged)
            .on("dragend", dragended);
 
    function dragstarted(d) {
        d3.event.sourceEvent.stopPropagation();
        
        d.fixed |= 2;         
    }
    function dragged(d) {
       
        var mouse = d3.mouse(svg.node());
        d.x = xScale.invert(mouse[0]);
        d.y = yScale.invert(mouse[1]);
        d.px = d.x;         
        d.py = d.y;
        force.resume();
    }
 
    function dragended(d) {
        
        d.fixed &= ~6;           }
 
    var force = d3.layout.force()
        .charge(-120)
        .linkDistance(30)
        .size([width, height]);
 
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
 
    svg.call(zoomer);
    
        force
            .nodes(graph.nodes)
            .links(graph.links)
            .start();
 
        var link = svg.selectAll(".link")
            .data(graph.links)
          .enter().append("line")
            .attr("class""link")
            .style("stroke-width"function (d) { return Math.sqrt(d.value); });
 
        var node = svg.selectAll(".node")
            .data(graph.nodes)
          .enter().append("circle")
            .attr("class""node")
            .attr("r"5)
            .style("fill"function (d) { return color(d.group); })
            .call(drag);
 
        node.append("title")
            .text(function (d) { return d.name; });
 
        force.on("tick",tick);
 
    function tick(){            
            link.attr("x1"function (d) { return  xScale(d.source.x); })
                .attr("y1"function (d) { return yScale(d.source.y);  })
                .attr("x2"function (d) { return xScale(d.target.x); })
                .attr("y2"function (d) { return yScale(d.target.y); });
 
            node.attr("transform"function (d) {
                return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")";
            });
  
 
        };
</SCRIPT>
cs





+ Recent posts