Adobe Lightroom Classic กับปัญหา Memory Leak บน Apple Silicon พร้อมวิธีแก้ปัญหา
เครื่อง Mac ทั้งหลายน่าจะเป็นอุปกรณ์ที่ช่างภาพใช้เป็นอันดับต้น ๆ เลยก็ว่าได้ โดยเฉพาะในยุคของ Apple Silicon เองที่ Apple ออกมาชูหาง กลุ่มคนที่ถ่ายรูป และ ตัดต่อวีดีโอเยอะเกินหน้าเกินตาไปมา ว่า Apple Silicon เร็วแบบนั้นแบบนี้กับงานของคุณ และแน่นอนว่า Application สามัญประจำเครื่องของเหล่าช่างภาพ ก็น่าจะหนีไม่พ้น Adobe Lightroom Classic (บางคนก็ย้ายไปใช้ CC แล้วก็ยินดีด้วย คุณ Move on ได้แล้ว) แต่.... มันมีปัญหากับ Apple Silicon ละสิ
ปล. ถ้ามาแค่อยากได้วิธีแก้ปัญหา ลงไปอ่านด้านล่างเลย ข้ามการ Investigate ไป
ปัญหาที่เจอ
ก่อนอื่น เครื่องที่เราใช้เป็น Macbook Pro 14-inch M1 Max 32 Cores GPU ใช้ Unified Memory ขนาด 32 GB เรียกว่าเกือบสุดแล้วก็ว่าได้ ดูแล้ว เออ SoC ก็ตัวสูงสุดแล้วที่จะใส่ได้ กับ Unified Memory ก็เกือบสุดแล้ว ไม่น่าจะมีปัญหาได้แล้วแหละ ถ้าคุณคิดแบบนี้ คุณคิดผิดครับ !
ปัญหาที่เราเจอเลยคือ เมื่อเราใช้งาน Lightroom ไปเรื่อย ๆ โดยเฉพาะเมื่อเราเข้าหา Develop แล้วนั่งทำรูปไป Memory ที่ Lightroom ใช้มันขึ้นไปเยอะมหาศาลมาก ๆ โดยที่เรายังไม่ได้ทำ Task ที่เป็น Memory Intensive อย่างการต่อ Panorama หรือ HDR Merging เลยนะ เราแค่แต่งใน Develop ทั่ว ๆ ไปเลย อาจจะใส่พวก Masking ไปหน่อย
ตอนแรก เราก็ไม่รู้หรอกว่ามันใช้ Memory เยอะขึ้นเรื่อย ๆ แต่เราไปสังเกตช่วงหลัง ๆ ที่เราทำไปเรื่อย ๆ แล้วทำไม อยู่ดี ๆ ความลื่นไหลมันช้า มันไม่ได้เหมือนช่วงแรก ๆ ที่มันลื่น ๆ กดแล้วมาเลย จนไปเห็น Memory นี่แหละ ว่ามันเยอะมาก ๆ
ถามว่ามันเต็มขนาดไหน มันเต็มขนาดที่ทำให้ Unified Memory ขนาด 32GB ของเราไม่พอแล้วต้องไปพึ่งพา Swap Memory ได้เลยละ (เรากำลังพูดถึงหลักร้อย GB เลยในบางครั้ง) ซึ่งเอาจริง ๆ คือ เห้ย บ้าเหรอ เครื่อง Memory เยอะขนาดนั้น แต่ทำไมมันยังแตกได้ ถ้าเป็นจริง ๆ เครื่องเล็กกว่านี้อย่าง 8 หรือ 16 GB ไม่แตกตายไปแล้วเหรอ
จากการเป็น Programmer เราวินิฉัยอาการได้อย่างรวดเร็วเลยว่า ปัญหาน่าจะเป็น Memory Leak แน่ ๆ หรือพูดง่าย ๆ คือ Memory มันรั่วนั่นเอง มันเกิดจากการที่โปรแกรมมันจอง Memory เพื่อใช้ในการเก็บข้อมูลบางอย่าง แล้วพอมันใช้เสร็จ มันดันไม่คืนระบบ แล้วก็จองแบบนี้ไปเรื่อย ๆ ทำให้สุดท้าย Memory ก็จะหมด ระบบจึงเริ่มไปพึ่งพวก Swap หรือการเอาข้อมูลบน Unified Memory ไปเก็บไว้ใน SSD ของเราแทน ทำให้ช้ากว่ามาก ๆ
Problem Investigation
เพราะเกิดเรื่องนี้ขึ้นเราเลยพยายามที่จะ Investigate ให้ลึกขึ้นไปอีกโดยการพยายามที่จะ Reproduce Issue ที่เกิดขึ้น ปรากฏว่า มันทำได้ง่ายมาก ๆ เพียงแค่เราเปิด Lightroom แล้วพยายามนั่งทำรูปไปเรื่อย ๆ เราจะเจอทันทีอย่างหลีกเลี่ยงไม่ได้เลย
ตอนนั้นเราตั้งสมมุติฐานว่า หรือเป็นเพราะ Adobe Camera RAW หรือไม่ที่เป็นตัว Process RAW File งั้นเราเลยลองทำงานกับ JPG ที่ไม่ต้องผ่าน Camera RAW แทน ปัญหามันก็ทุเลาลงนะ อาการ Memory Leak ก็ยังคงอยู่ แต่มัน Leak ในอัตราที่ช้ากว่าก่อนหน้ามาก ๆ แปลว่า มันก็น่าจะยังไม่ได้เป็นต้นตอของปัญหา
เราเลยตั้งสมมุติฐานใหม่ว่า มันน่าจะเกิดจากพวก Module สำหรับการทำ Image Processing หรือไม่ เพราะไม่ว่าเราจะใช้ RAW หรือ JPG มันก็แตกหมด งั้นน่าจะเป็นอะไรที่ Common กว่านั้น แล้วก่อนที่เราจะเข้า Develop มันก็ไม่ได้เป็นหนักมากเท่าไหร่ หรือเป็นเพราะเรื่องนี้กันแน่ สุดท้าย ก็ยังไม่รอดอยู่ดี
จนเราไม่รู้จะทำยังไงละ เราเลยลองเปิด Lightroom อยู่ในหน้า Develop ไว้เฉย ๆ แล้วทิ้งไว้เลย ปรากฏว่า เข้ Memory ที่ Lightroom ใช้มันก็งอกออกมาเรื่อย ๆ เหมือนกัน แต่ช้ากว่า 2 การทดลองแรกอยู่ แต่ก็เพิ่มอยู่ดี และไม่มีแนวโน้มว่าจะลดลงเลย อื้ม... ยากแล้วเอาไงต่อดี
Catalog sizeish..... may be?
เราเลยไปตั้งสมมุติฐานใหม่ว่า หรือเป็นเพราะขนาดของ Catalog File เราเหรอ เพราะเราเป็นคนที่ใช้ 1 Catalog เก็บทุกอย่างหมดเลย ทำให้ใน Catalog ของเรามีรูปหลักแสนรูปอยู่ในนั้นหมดเลย
ถ้าเราบอกว่าเป็นเพราะขนาดของ Catalog จริง ๆ งั้นเราลองสร้าง Catalog File ใหม่เลย เพื่อเป็นการควบคุมตัวแปร เราจะลองเปิดทิ้งไว้ เริ่มจาก Catalog เปล่า ๆ เลย ไม่มีสักรูปอยู่ในนั้นเลย เราก็เปิดทิ้งไว้แบบนั้นแหละอาการ Memory Leak หายไปเฉย แล้วพอ เราเอารูปใส่เข้าไปแล้วเปิดทิ้งไว้ก็เจออาการ Memory Leak เลยลองเข้า Develop ก็คือได้อาการเดียวกับตอนแรกเป๊ะ ๆ
ดังนั้น เราเลยลองใหม่ ลองสร้าง Catalog ที่มีจำนวนรูปมากขึ้น จากเดิม Sony RAW 200 รูป เปลี่ยนเป็น 400 รูป เปิดทิ้งไว้เหมือนเดิม ปรากฏว่า อาการมันหนักขึ้น Memory Leak หนักขึ้นอย่างเห็นได้ชัดเลยทำให้ เราเริ่มปักใจแล้วว่า น่าจะเป็นเพราะ ขนาดของ Catalog แน่ ๆ
จากตอนที่เราไม่มีรูปใน Catalog เลย แล้วไม่เจอปัญหานี้เลย การใช้งาน Memory ก็ขึ้น ๆ ลง ๆ ด้วยไม่ได้เพิ่มเหมือนก่อนหน้านี้แล้ว ทำให้เราเริ่มกลับมาสงสัยที่ Image Processing Module ของ Lightroom แล้วว่า มันมีอะไรแน่ ๆ
Hardware Acceleration Settings is the PROBLEM !
สำหรับคนที่ใช้งาน Lightroom เราจะรู้กันดีว่า ถ้าเรามี GPU จะช่วยเร่งการทำงานของระบบให้เร็ว และ ลื่นขึ้น เช่นเวลาเราลาก Adjustment มันก็จะลื่นขึ้น หรือเวลา Export ก็จะเร็วขึ้นด้วยประมาณนึง ซึ่งใน Apple Silicon มันก็มี GPU มาให้เราเหมือนกัน
พวก Image Processing แน่นอนว่า มันต้องทำงานบน GPU แน่ ๆ เราเลยสงสัย ตั้งสมมุติฐานว่า มันน่าจะมีปัญหาอะไรแน่ ๆ เพื่อเป็นการทดสอบ เราเลยปิดไปเลย แล้วลองกับ Catalog อันแรกที่ขนาดใหญ่ ๆ ที่เราใช้งานประจำเลย ลองเปิดทิ้งไว้ และ ลอง Develop รูปก็แล้ว อาการ Memory Leak ก็หายไปเลย มันจะมีบางครั้งมันเรียก Memory เยอะเช่นตอนที่เราทำ Mask เยอะ ๆ แต่สุดท้ายพอเราเปลี่ยนรูปมันก็คืน Memory กลับมา แปลว่าหายแล้วละ
แต่ในรอบก่อนหน้าที่เราลองสร้าง Catalog เปล่า ๆ โดยที่เปิด Hardware Acceleration มันก็ไม่ได้เป็นอะไรนะ เราเลยคิดว่า ถ้าเราเปิด Hardware Acceleration แล้วเลือกให้เปิดเฉพาะ Display เท่านั้น น่าจะหาย ถ้าหายจริง ๆ ปัญหามันน่าจะเป็นเพราะ Image Processing Module อย่างที่เราคิด สุดท้าย ลองทำดู ก็คือ ใช่อย่างที่คิดเลย ดังนั้น ปัญหามันน่าจะอยู่ที่ Image Processing บน GPU อย่างที่เราคิดแล้วละ
Unified Memory Architecture (UMA) might be the actual problem
อันนี้เราเดาแล้วนะ เราเดาว่า ตอนที่ Adobe Optimise Lightroom Classic เข้ามาเป็น Native Apple Silicon แล้วไม่น่าจะได้ดีลกับขนาดของ Memory เพราะ Concept มันค่อนข้างต่างกันเลย
จากเดิม ระบบของเรามี Memory บน CPU คือ RAM และ GPU ก็มี RAM เป็นของตัวเองเหมือนกัน เวลาเราเขียนให้ระบบมอง เราก็สามารถเรียกค่าของขนาดของ Memory ทั้งสองด้านออกมาได้เลย เช่น CPU เรามี 32 GB และ GPU เรามี 16 GB มันก็แยกชิ้นกันอย่างชัดเจน
แต่ใน Unified Memory Architecture (UMA) มันไม่เหมือนกัน เพราะ Memory ของทั้ง GPU และ CPU มันเป็น Pool เดียวกัน เป็น Memory ชุดเดียวกัน ข้อดีคือ เวลาเราจะให้ GPU เข้าถึงข้อมูล แทนที่เราจะต้องเสียเวลาย้ายไป เราก็แค่ให้ที่อยู่กับ GPU ไปแล้วเข้าถึงได้เลย ทำให้การทำงานมันเร็วมากขึ้นมาก ๆ
แต่ปัญหาคือ เวลาเรามองขนาดของ Memory นี่แหละ ชิบหาย เพราะเวลาเราเรียกขนาดของ CPU Memory ที่มันจะให้ได้ มันจะไปเท่ากับ GPU Memory ที่เรามี ทำให้โปรแกรมมันน่าจะรับรู้ได้ว่า เรามี GPU Memory เหลือเยอะมาก ๆ เลยนะ ทั้งที่จริง ๆ แล้ว Pool นี้เราไม่ได้ใช้งานคนเดียวนะ CPU ต้องใช้ด้วยกับเรานะ ชิบหายแล้วทีนี้
เพราะโปรแกรมมันก็แหม่ ฉลาดแหละ ว่า ถ้าเกิดเรามี Memory เหลือ งั้นเราก็ Pre-Process อะไรบางอย่างเก็บไว้ก่อนมั้ยละ แล้วถ้าเราเรียกใช้จริง ๆ เราก็ดึงจาก Memory ขึ้นมาได้เลย แทนที่จะต้องมานั่งรอ Process ตอนนั้น แล้วพอเห็นว่าเรามี Memory เยอะ ก็ Cache ได้เพียบเลยสิ เราตั้งข้อสมมุติฐานนี้ เพราะตอนที่เราลองเพิ่มขนาดของ Catalog แล้วปล่อยทิ้งไว้ ดูปรากฏว่าอาการนี้มันหนักขึ้นเรื่อย ๆ
Performance Impact
การที่เราปิด Feature Hardware Acceleration อย่างการใช้ GPU ไป แน่นอนว่า Performance ก็ลดลงด้วยเช่นกัน เพราะทุกอย่างแทนที่จะแบ่งไปให้ GPU จัดการ กลายเป็นว่า CPU ต้องจัดการเองทุกอย่าง เรามาลอง Benchmark กันดีกว่าว่า เราต้องเสีย Performance ไปขนาดไหน
เริ่มจากการ Develop รูปกันก่อน เราลองกับไฟล์ RAW แบบ Lossless Compressed จาก Sony A7IV ในแง่ของความรู้สึก เรามองว่า มันไม่ต่างเลยนะ เราลากอะไรมันก็ไปเลยหมด เรียกว่า ไม่มีอาการแลค หรือต้องรออะไรเลย ควารู้สึกไม่ต่างกันเลย แต่มันจะไปรู้สึกเมื่อเราลองทำไปหลาย ๆ รูป การปิด Hardware Accleration ให้ประสบการณ์ที่นิ่งตลอดการทำงานใน 1 อัลบั้มเลย ไม่มีใช้ ๆ ไปแล้วกระตุกเลย
มาที่การ Export กันบ้าง อันนี้แหละ น่าจะเห็นความต่างบ้างแหละ เราจะทำการ Export รูปออกมาทั้งหมด 78 รูป จะมาจากกล้อง Sony A7III และ Fujifilm X-T4 เป็น RAW File ทั้งหมด และเกือบทั้งหมดเป็นรูปที่มีการทำ Adjustment ทั้งหมด ทำให้น่าจะต้องใช้พลังในการ Process อยู่พอสมควร
จากการทดลองของเรา ถ้าเราใช้ และ ไม่ใช้ GPU จะได้เวลาออกมาเป็น 63.5 และ 41 วินาทีตามลำดับเลย หรือถ้าเราคิดก็คือ ถ้าเราไม่เปิดการใช้งาน GPU สำหรับ M1 Max เวลาจะเพิ่มขึ้นมาถึง 35.33% กันไปเลย สำหรับเรา เรามองว่ามันเยอะมาก ๆ
สรุป : Solution คือปิดการใช้ GPU ก็จบ
ปัญหาทั้งหมดเกิดจาก Memory Leak เมื่อเราเปิดการใช้งาน Hardware Accelation โดยการเข้าไปที่ Preferences > Performance > Camera Raw > Use Graphic Processor เปลี่ยนเป็น Custom แล้วติ๊กเฉพาะ Use GPU for display หรือ เลือกเป็น Off เลยก็ได้ปลอดภัยหมด เราลองกับ M1, M1 Pro และ M1 Max ทำแบบนี้อาการ Memory Leak หายหมด แต่อาการนี้เกิดกับ Apple Silicon Mac เท่านั้นนะ Intel-Based Mac ไม่ได้รับผลกระทบในครั้งนี้ หวังว่า Adobe และ Apple จะแก้ปัญหานี้โดยเร็วผ่าน Software Update เนอะ