1 คะแนน โดย GN⁺ 2024-07-14 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เนื่องจากภาระคำขอที่สูง Lichess จึงเปลี่ยนจากการสแกนบล็อกทั้งหมดมาเป็น การตรวจสอบความถูกต้องเมื่ออ่าน หลังจากการตรวจสอบ RAID ตามรอบของ เซิร์ฟเวอร์ 7-piece Syzygy tablebase ทำได้ไม่ทัน
  • เพื่อย้าย tablebase ขนาด 17TiB โดยไม่ต้องหยุดให้บริการเป็นเวลาหลายชั่วโมง จึงเตรียมเซิร์ฟเวอร์ใหม่ และทดสอบด้วยการเล่นซ้ำล็อกคำขอจริงในสภาพแวดล้อม RAM 32GiB, NVMe 2×201GiB และ HDD 6×5.46TiB
  • จากการเล่นซ้ำ คำขอ 1 ล้านรายการ ที่บันทึกจากโปรดักชันด้วยไคลเอนต์ขนาน 12 ตัว พบว่าคอขวดหลักไม่ใช่เวลาตอบสนองเฉลี่ย แต่เป็น tail latency ที่ผู้ใช้รับรู้ได้
  • ในด้านการใช้งานจริง pread(2) ได้เปรียบกว่า mmap ทั้งในการจัดการข้อผิดพลาดและ tail latency ส่วน hint สำหรับการเข้าถึงแบบสุ่มอย่าง POSIX_FADV_RANDOM และ MADV_RANDOM มักให้ผลตรงกันข้าม
  • นำ table prefix ไปไว้บน SSD ที่มีพื้นที่จำกัด และทำ parallelization ของ probe ภายในคำขอ เพื่อลดการเข้าถึงดิสก์ที่ช้า พร้อมตรวจสอบว่าการปรับปรุงใน benchmark ส่งผลต่อเวลาตอบสนองในโปรดักชันด้วยหรือไม่

เปลี่ยนจากการตรวจสอบ RAID ทั้งหมดมาเป็นการตรวจสอบเมื่ออ่าน

  • เซิร์ฟเวอร์ 7-piece Syzygy tablebase ของ Lichess ทำการตรวจสอบความถูกต้องของ RAID ตามรอบให้เสร็จได้ยากในช่วงที่มีคำขอ tablebase จำนวนมาก
  • การตั้งค่าใหม่ใช้ dm-integrity on LVM โดยไม่ตรวจสอบบล็อกข้อมูลทั้งหมดตามรอบ แต่จะ ตรวจสอบทุกครั้งที่มีการอ่าน บล็อก
  • เพื่อย้าย tablebase ขนาด 17TiB โดยไม่ต้องหยุดให้บริการเป็นเวลาหลายชั่วโมง จึงตั้งค่าเซิร์ฟเวอร์ใหม่แยกต่างหาก
    • ก่อนสลับจริง สามารถรัน benchmark แบบควบคุม กับ tablebase ทั้งหมดได้
    • จากนั้นจึงสลับไปยังเซิร์ฟเวอร์ใหม่ และปลดระวางเซิร์ฟเวอร์เดิม

การตั้งค่าเซิร์ฟเวอร์ใหม่

  • RAM ยังคงเป็น 32GiB เท่าเดิม
  • พื้นที่จัดเก็บเพิ่ม NVMe 2×201GiB ซึ่งไม่มีในเซิร์ฟเวอร์เดิม และกันพื้นที่ที่เหลือของดิสก์ 476GiB ไว้สำหรับ OS และพื้นที่ทำงาน
  • HDD เพิ่มจากเดิม 5 ลูกเป็น HDD 6×5.46TiB
  • ระบบปฏิบัติการคือ Debian bookworm และเคอร์เนลอยู่ในตระกูล Linux 6.1.0-21-amd64
  • I/O scheduler เริ่มต้นถูกเลือกเป็น none สำหรับ NVMe และ mq-deadline สำหรับ HDD

การตั้งค่าและการมอนิเตอร์ RAID 5

  • RAID 5 เหมาะกับเซิร์ฟเวอร์ tablebase เพราะกู้คืนจากดิสก์เสีย 1 ลูกได้ และกระจายการอ่านแบบสุ่มไปยังดิสก์หลายลูกได้
  • การตั้งค่าเริ่มต้นเป็นดังนี้
lvcreate --type raid5 --raidintegrity y --raidintegrityblocksize 512 --name tables --size 21T vg-hdd
  • ประสิทธิภาพในการทดสอบช่วงแรกถือว่าใช้ได้ แต่หากไม่มีการมอนิเตอร์ อาจพลาดปัญหาที่ดิสก์บางลูกไม่ได้มีส่วนร่วมในระดับเดียวกัน
  • หากละ --stripes จะไม่ได้ใช้ physical volume ทั้งหมดเป็นค่าเริ่มต้น
  • จำเป็นต้องมี การมอนิเตอร์กิจกรรมการอ่านแยกตามดิสก์ เพื่อจับการตั้งค่า RAID ที่ผิดพลาด

คอขวดที่เห็นจากล็อกคำขอจริง

  • ภายใต้เงื่อนไขปกติ เซิร์ฟเวอร์ได้รับ 10–35 คำขอต่อวินาที
  • บันทึก คำขอ 1 ล้านรายการ ในสภาพแวดล้อมโปรดักชัน แล้วให้ไคลเอนต์ขนาน 12 ตัวส่งคำขอเหล่านั้นตามลำดับในสถานการณ์ที่เลือก
  • table จะถูกเปิดแบบ lazy open และแคชของแอปพลิเคชันกับ OS จะค่อย ๆ ถูกเติม
    • ตัดเวลาตอบสนอง 800,000 รายการแรก ออกในฐานะช่วง warm-up
    • จากนั้นวิเคราะห์เวลาตอบสนองของ 200,000 คำขอ ถัดมา
  • เวลาตอบสนองเฉลี่ยเร็วพอแล้ว แต่ tail latency สูง จึงกลายเป็นจุดโฟกัสของการปรับแต่ง
  • กราฟ ECDF แสดงสัดส่วนคำขอที่เร็วกว่าค่าเวลาตอบสนองแต่ละค่า โดยแกน x เป็นสเกลลอการิทึม
  • ในกราฟ มีการบวก 30ms ให้กับเวลาตอบสนองแต่ละค่า เพื่อสะท้อน ping time 30ms ของไคลเอนต์
    • เป็นการจัดการเพื่อไม่ให้แกน x แบบลอการิทึมเน้นความต่างไม่กี่มิลลิวินาทีในช่วงค่าต่ำมากเกินไป

pread(2) ได้เปรียบกว่า mmap

  • shakmaty-syzygy ซึ่งเป็น implementation ของ Syzygy tablebase มีอินเทอร์เฟซที่เปลี่ยนวิธีเปิดไฟล์ table และวิธีอ่านได้
  • ตัวเลือกหลักมีสองแบบ
    • mmap: map ไฟล์ table เข้าหน่วยความจำ และเมื่อเข้าถึงพื้นที่หน่วยความจำนั้น การอ่านดิสก์จะเกิดขึ้นแบบโปร่งใส
    • pread(2): ทำ system call ทุกครั้งที่อ่าน และรายงานข้อผิดพลาดการอ่านผ่านค่าที่คืนกลับมา
  • หลังจาก mmap แล้วไม่ต้องใช้ system call เพิ่ม แต่เพราะการอ่านดูเหมือนการเข้าถึงหน่วยความจำทั่วไป จึงต้องจัดการข้อผิดพลาดด้วยวิธี out-of-band เช่น signal
  • ใน implementation ของเซิร์ฟเวอร์ แค่การจัดการข้อผิดพลาดที่ทนทานกว่าก็เพียงพอที่จะทำให้การใช้ pread สมเหตุสมผล และใน benchmark สำหรับสถานการณ์ที่สนใจ ประสิทธิภาพของ pread ก็ดีกว่า
  • สาเหตุที่เป็นไปได้อย่างหนึ่งคือ เมื่อเข้าถึงบล็อกข้อมูลเดี่ยวที่ถูก memory-mapped แล้วข้ามขอบเขตของ page อาจทำให้เกิดการอ่านดิสก์สองครั้ง
  • ไม่จำเป็นต้องนำ pread ไปใช้กับเอนจินหมากรุกทันที
    • การใช้ tablebase ในแมตช์ของเอนจินมักเกิดขึ้นเมื่อสามารถวาง WDL table ทั้งหมดไว้บนสตอเรจที่เร็วพอได้
    • ในกรณีนี้ ช่วงเวลาตอบสนองทั่วไปเร็วถึงระดับที่ไม่ปรากฏบนกราฟนั้น และ memory mapping ที่ลด overhead ของ system call จะดีกว่า

hint การเข้าถึงแบบสุ่มที่ให้ผลตรงกันข้าม

  • posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM) และ hint ที่สอดคล้องกันสำหรับ memory map โดยรวมแล้วส่วนใหญ่ ให้ผลตรงกันข้าม
  • POSIX_FADV_RANDOM เป็น hint ที่บอก OS ว่าการเข้าถึงไฟล์เป็นแบบสุ่ม และ automatic read-ahead มีแนวโน้มไม่เป็นประโยชน์ เพื่อช่วยลดแรงกดดันต่อ page cache
  • รูปแบบการเข้าถึง tablebase เมื่อผู้คนวิเคราะห์ endgame อาจไม่ได้สุ่มเท่าที่คาด
  • ในเอนจินหมากรุก probe อาจกระจายไปยัง endgame ที่เป็นไปได้ต่าง ๆ มากกว่า ดังนั้นผลลัพธ์อาจแตกต่างกัน

table prefix ที่จะวางบน SSD พื้นที่จำกัด

  • table probe จะเข้ารหัสตำแหน่งเป็นดัชนีจำนวนเต็มก่อน โดยอิงจากข้อมูลการเข้ารหัสใน table header
  • จากนั้นต้องหาบล็อกข้อมูลแบบบีบอัดที่มีผลลัพธ์ของดัชนีนั้น
  • Syzygy มี sparse block length list ที่ชี้ไปใกล้รายการที่ถูกต้อง จากนั้นจึงใช้ block length list เพื่อหาบล็อกข้อมูลที่เกี่ยวข้อง
  • ขนาดของ table section เป็นดังนี้
Table section WDL DTZ Total
Headers and sparse block length lists 38GiB 9GiB 47GiB
Block length lists 274GiB 64GiB 339GiB
Compressed data blocks 8433GiB 8458GiB 16891GiB
  • อาจใช้พื้นที่ SSD เป็น adaptive cache layer เพื่อแคช hot list entry และ data block ได้
  • หากเป้าหมายคือการลด tail latency การวาง sparse block length list และ block length list ไว้บน SSD จะเหมาะสม เพราะคำนึงถึงกรณีแย่สุด
  • การจัดวางนี้สามารถจำกัดการอ่านดิสก์ช้าต่อ table probe ได้สูงสุด 1 ครั้ง ไม่ว่าจะเป็น hot หรือ cold
  • สำหรับเซิร์ฟเวอร์นี้ พื้นที่ SSD ไม่พอทำ RAID 1 mirroring และเพราะเป็นการปรับแต่งแบบเลือกใช้ได้ จึงยอมไม่ใช้ redundancy และใช้ RAID 0

parallelization ของ probe ภายในคำขอ

  • คำขอ tablebase ทั่วไปของเอนจินหมากรุกคือคำขอสำหรับค่า WDL เดี่ยว
  • ในอินเทอร์เฟซผู้ใช้ ต้องการแสดง ค่า DTZ สำหรับทุกตาเดิน
  • เมื่อรวมถึงการแก้ capture ภายใน Syzygy แล้ว คำขอเฉลี่ยจะก่อให้เกิด 23 WDL probe และ 70 DTZ probe
  • implementation เริ่มต้นทำ parallelization ของการประมวลผลคำขอเอง แต่ probe ภายในแต่ละคำขอทำแบบลำดับ
  • parallelism ที่ละเอียดขึ้นสร้าง overhead ในช่วง latency ต่ำ แต่ ลด tail latency ได้มาก
  • แม้ดิสก์จะไม่สามารถประมวลผลการอ่านขนานจำนวนมากในเชิงกายภาพได้จริง I/O scheduler ก็มีโอกาสวางแผนการอ่านให้แต่ละคำขอเสร็จเร็วขึ้น
  • วิธีนี้ช่วยให้จัดลำดับการเข้าถึงดิสก์ที่เกี่ยวข้องได้ดีขึ้น เพื่อลดเวลารอจนกว่าหัวอ่านดิสก์จะไปถึงเซกเตอร์ของคำขอถัดไป

การยืนยันในโปรดักชันและข้อมูลต้นฉบับ

  • ตรวจสอบด้วยกราฟเวลาตอบสนองว่า การปรับแต่งจากสถานการณ์ benchmark ช่วยในโปรดักชันจริงหรือไม่
  • ข้อมูลต้นฉบับเผยแพร่ไว้ที่ lila-tablebase-bench

1 ความคิดเห็น

 
GN⁺ 2024-07-14
ความคิดเห็นบน Hacker News
  • Lichess เป็นบริการที่ทำให้ต้องหยุดชื่นชมเหมือนไวน์ดี ๆ เป็นสิ่งที่ยอดเยี่ยมมากสำหรับชุมชนหมากรุก และผมใช้ทุกวันพร้อมกับได้รับแรงบันดาลใจจากฟีเจอร์และประสิทธิภาพของมันอยู่เสมอ
    ยิ่งน่าทึ่งเข้าไปอีกเมื่อรู้ว่าเป็นทีมขนาด 1~2 คน ที่มีงบประมาณจำกัด

    • ต้องไม่ลืมด้วยว่ามันฟรีและเป็น โอเพนซอร์ส ไม่เคยเรียกเงิน และจะไม่ทำแบบนั้นในอนาคตด้วย หลายคนบริจาคให้ มีการเปิดเผยค่าใช้จ่าย และยังมีแอปด้วย
    • อยากให้ ซอฟต์แวร์โอเพนซอร์ส สำหรับผู้ใช้ปลายทางจำนวนมากขึ้นเป็นมิตรกับผู้ใช้ ออกแบบดี และดูแลรักษาดีเหมือน Lichess
    • ผมก็รู้สึกแบบนั้นเหมือนกัน แอปมือถือเบต้า ตัวใหม่ล่าสุดดูสะอาดขึ้น และยังมี haptic feedback ด้วย เจ๋งมาก
    • สักวันหนึ่งอยากสร้างอะไรที่มีคุณค่าและเจ๋งได้เท่า Lichess
  • ส่วนที่แสดง ECDF ที่บวก 30ms ให้กับเวลาตอบสนองแต่ละครั้งน่าสนใจมาก
    การบวกค่าคงที่อาจดูเหมือนทำขึ้นแบบฝืน ๆ แต่จริง ๆ แล้วเป็นวิธีดูผลลัพธ์จากมุมมองของไคลเอนต์ที่มี ping 30ms และช่วยไม่ให้แกน x แบบสเกลลอการิทึมไปขยายความต่างไม่กี่ ms ในช่วงค่าต่ำมากเกินไป อาจเป็นเทคนิคมาตรฐานก็ได้ แต่ดูเหมือนทริกที่ค่อนข้างฉลาด

  • สงสัยว่าจำเป็นต้องลดต้นทุนจริง ๆ หรือเปล่า หรือมีเหตุผลอื่นที่ทำให้ใส่ SSD 20TB ลงในเครื่องเดียวแล้วจบไม่ได้ SSD 4TB ก็ราว ๆ 300 ดอลลาร์ และไดรฟ์ SFF ของ HP หรือ Dell ก็ไม่ได้แพงกว่านั้นมากนัก
    น่าจะเป็นเพราะเขาสนใจการทดสอบและการเพิ่มประสิทธิภาพเองด้วย และถ้ามองจากมุมผลิตภัณฑ์ ก็คงเอาเวลาที่มีจำกัดไปใช้กับโปรเจกต์อื่นมากกว่า

    • Lichess เป็นองค์กร ไม่แสวงหากำไร และมีอาสาสมัครจำนวนมาก ดังนั้นสมดุลระหว่างต้นทุนเวลาและฮาร์ดแวร์จึงน่าจะแตกต่างจากบริษัทแสวงหากำไรส่วนใหญ่
    • Lichess เป็น องค์กรไม่แสวงหากำไร ที่ดำเนินงานด้วยเงินบริจาคและอาสาสมัครเท่านั้น พนักงานมีเพียงคนเดียวคือผู้ก่อตั้งองค์กรไม่แสวงหากำไรนี้ และดูเหมือนว่าเขารับเงินน้อยกว่าที่จะหาได้จากงานอื่นมากเมื่อเทียบกับความสามารถของเขา
      องค์กรตั้งอยู่ในฝรั่งเศส ซึ่งไม่รู้ว่าส่งผลต่อต้นทุนอย่างไรบ้าง แต่ก็น่าพูดถึง
    • งานนี้ลด เวลาตอบสนองสูงสุด ลงได้ในระดับหนึ่งหลัก ถ้าโปรเจกต์ใช้เวลา 1 สัปดาห์ หรืออย่างมาก 2 สัปดาห์ และลดเวลาตอบสนองของผู้ใช้บางส่วนจาก 15 วินาทีเหลือ 1.5 วินาที ก็ถือว่าคุ้มค่าแล้ว
      ถ้าจะหาเหตุผลให้การลงทุนเวลาคุ้มกว่านี้ ก็คงต้องเป็นโปรเจกต์ที่ประสบการณ์ผู้ใช้แย่กว่านี้ หรือเป็นกรณีองค์กรแสวงหากำไรที่ยอมรับว่ามีโอกาสหาเงินจากที่อื่นและไม่ค่อยสนใจความเจ็บปวดของลูกค้า
    • วิศวกรที่คิดว่าเป็น “การทดสอบและเพิ่มประสิทธิภาพเพื่อความสนุก” น่าจะหาได้ยากมากในอุตสาหกรรมอื่นนอกจาก IT
      ดูเหมือนเป็นผลรวมของฮาร์ดแวร์ที่ทรงพลังและถูกเกินไป กับคนขี้เกียจที่อยากบอกว่า “วันนี้พอแค่นี้” เสียมากกว่า เขาก็พูดกันไม่ใช่หรือว่าให้ภูมิใจกับงานของตัวเอง
    • ถ้ามองจากมุมผลิตภัณฑ์ก็พอเข้าใจ แต่ Lichess ไม่ใช่ บริษัทแสวงหากำไร ที่มีผลิตภัณฑ์ หากดำเนินงานจริงในฐานะองค์กรไม่แสวงหากำไร ดังนั้นถ้าจะเข้าใจการตัดสินใจ ต้องเปลี่ยนมุมมองก่อน
  • การเพิ่มประสิทธิภาพนี้มีตัวเลือกบางอย่างที่น่าสงสัย เหตุผลของการเพิ่มประสิทธิภาพคือมีกิจกรรม I/O มากเกินไปจน การตรวจสอบ RAID ทำไม่เสร็จ
    จากบทความอย่างเดียว ยังไม่ชัดเจนว่าการตรวจสอบ RAID กับข้อมูล 17TiB เคยเสร็จจริงหรือไม่ แทนที่จะทำแบบนั้น เขาปิดการตรวจสอบ RAID ตามรอบ แล้วเปลี่ยนเป็นตรวจข้อผิดพลาดเป็นรายหน้าเมื่ออ่านข้อมูล ซึ่งสองวิธีนี้ไม่เหมือนกัน และถ้าเป็นข้อมูลสำคัญก็ควรใช้ทั้งคู่
    ถ้าพบความเสียหายก็ต่อเมื่อพยายามอ่านข้อมูล ความเสียหายของข้อมูลเก่าอาจค้างอยู่ต่อไป และอาจเลยระยะเวลาเก็บสำรองจนกู้คืนต้นฉบับไม่ได้ นอกจากนี้ยังมีเรื่องที่เปลี่ยนไปใช้ RAID 0 ด้วย ซึ่งแม้จะเป็นตัวเลือกที่เร็วที่สุด แต่ก็เท่ากับเชื่อค่อนข้างมากว่าชุด NVMe นั้นจะรับโหลดแบบนั้นไหว
    หวังว่าจะมีการสำรองข้อมูลไว้อย่างดี ทางออกที่ดีคือเปิดเซิร์ฟเวอร์ชั่วคราว กู้คืนแบ็กอัปและตรวจสอบข้อมูลทั้งหมด จากนั้นถ้าสำเร็จก็จะได้ตรวจยืนยันขั้นตอนแบ็กอัป/กู้คืนและความสมบูรณ์ของไฟล์ไปพร้อมกันด้วย ถึงอย่างนั้นก็ควรมีพื้นที่พอให้การตรวจสอบ RAID บนเซิร์ฟเวอร์หลักทำจนเสร็จ และไม่ควรใช้ RAID 0 ด้วยเหตุผลด้านประสิทธิภาพ

    • จริงที่สองวิธีนี้ไม่เหมือนกัน แต่สำหรับ use case นี้ก็เพียงพอแล้ว เพราะถ้าพบว่าข้อมูลเสีย ก็ทิ้งไฟล์แล้วดาวน์โหลดใหม่หรือสร้างใหม่ได้
      นี่เป็นชุดข้อมูลที่หาได้อย่างอิสระ เพียงแต่มีขนาดค่อนข้างใหญ่ https://en.wikipedia.org/wiki/Endgame_tablebase อธิบายได้ดีกว่า ดังนั้นจึงไม่ได้สำรองข้อมูลด้วย
  • lishogi ก็มีเหมือนกัน แต่ตอนนี้ยังมีขนาดเล็ก จึงยังไม่ถึงขั้นต้องใช้การเพิ่มประสิทธิภาพแบบนี้
    ในบรรดาหมากรุกสายพันธุ์ต่าง ๆ โชงิน่าสนุกที่สุด ส่วนเซี่ยงฉีไม่ถึงขั้นนั้น

  • สงสัยว่า lichess หมายถึง lich ผู้หญิงหรือเปล่า แบบ baron/baroness อะไรทำนองนั้น

    • ยศขุนนางไม่ใช่ตัวเทียบที่ดีนัก เพราะเป็นตัวอย่างหายากที่มีรากศัพท์เฉพาะเพศชายจริง ๆ และคำส่วนใหญ่รากศัพท์เป็นกลาง แม้จะมีรูปเพศชายหรือเพศหญิงก็ต้องใช้อุปสรรค/ปัจจัยต่อท้าย
      ถ้าพูดให้เคร่งครัด lich เพศชายคือ “werlich” ส่วน lich เพศหญิงคือ “wiflich” และรูปพหูพจน์เติม “-en” อย่างไรก็ตาม เพศมักไม่ค่อยเกี่ยวกับอันเดด ดังนั้นรูปกลางจึงถูกใช้มากอย่างท่วมท้น
      “lichess” เป็นการผสมรากศัพท์เยอรมันกับฝรั่งเศสที่ประหลาด จนไม่สามารถแยกจากคำอื่น ๆ ในภาษาอังกฤษได้อย่างเป็นธรรมชาติ
    • หมายถึง Libre chess หรือหมากรุกเสรีและโอเพนซอร์ส
  • แม้จะไม่ใช่การเปรียบเทียบที่ยุติธรรม แต่ คุณภาพวิศวกรรม ของทีม Lichess ทำให้ทึ่งจริง ๆ คู่แข่งหลักคุยเรื่องการย้ายไป GCP แต่ก็ยังเจอปัญหาล่มซ้ำ ๆ ตามความนิยมที่เพิ่มขึ้น และผมคิดว่ามีพนักงานมากกว่าประมาณ 100 เท่า
    จุดอ่อนของ Lichess เคยเป็นแอปมือถือ แต่ v2 ที่ทำใหม่ด้วย Flutter แม้ยังเป็นเบต้า ก็ถือว่าดีมากแล้ว
    และควรจำไว้ด้วยว่า Thibault รับค่าตอบแทนของตัวเองไม่ถึงปีละ 60,000 ดอลลาร์

    • ผมว่าไม่จำเป็นต้องรู้สึกผิดถ้าจะขึ้นเงินเดือนให้ตัวเอง เพิ่มเป็นปีละ 200,000 ดอลลาร์ เพื่อให้ชีวิตสบายขึ้น น่าจะส่งผลดีต่อโปรเจกต์ในระยะยาวอย่างแน่นอน
    • Lichess เป็นบริการที่ยอดเยี่ยมสำหรับผู้เล่นหมากรุกแบบสบาย ๆ อย่างผมในการหาคนเล่นด้วยได้เร็ว ๆ แทบไม่ต้องรอเลย
      แต่สงสัยว่าควรออกเสียง Lichess อย่างไร Lie chess หรือ Le chess หรือ League chess
    • Lichess ดูเหมือนเป็นตัวอย่างที่ดีว่า Wikipedia น่าจะมีประสิทธิภาพได้มากแค่ไหนทั้งในด้านโค้ดและองค์กร
    • คุณน่าจะประเมินจำนวนนักพัฒนาของ Chess.com สูงเกินไปพอสมควร