มีปัญหาอะไรบ้างที่ให้ผลดีกับการคำนวณ GPU


84

ดังนั้นฉันมีหัวที่ดีสำหรับปัญหาที่ฉันทำงานด้วยเป็นหนึ่งที่ดีที่สุดในอนุกรมและที่สามารถจัดการในแบบคู่ขนาน แต่ตอนนี้ฉันไม่ได้มีความคิดอะไรมากเกี่ยวกับสิ่งที่จัดการได้ดีที่สุดโดยการคำนวณโดยใช้ CPU และสิ่งที่ควรลดการใช้ GPU

ฉันรู้ว่ามันเป็นคำถามพื้นฐาน แต่การค้นหาส่วนใหญ่ของฉันได้ถูกจับในผู้คนอย่างชัดเจนเรียกร้องให้หนึ่งหรืออื่น ๆ โดยไม่ต้องพิสูจน์ว่าทำไมจริงหรือค่อนข้างกฎของหัวแม่มือที่คลุมเครือ กำลังมองหาคำตอบที่มีประโยชน์มากขึ้นที่นี่

คำตอบ:


63

ฮาร์ดแวร์ GPU มีจุดแข็งอยู่สองประการ: การประมวลผลแบบดิบ (FLOP) และแบนด์วิดท์หน่วยความจำ ปัญหาการคำนวณที่ยากที่สุดตกอยู่ในหนึ่งในสองประเภทนี้ ตัวอย่างเช่นพีชคณิตเชิงเส้นหนาแน่น (A * B = C หรือ Solve [Ax = y] หรือ Diagonalize [A] ฯลฯ ) จะอยู่ที่ใดที่หนึ่งบนสเปกตรัมแบนด์วิดท์การคำนวณ / หน่วยความจำขึ้นอยู่กับขนาดของระบบ Fast Fourier transforms (FFT) ยังพอดีกับโมลด์ที่ต้องการแบนด์วิดธ์รวมสูง เช่นเดียวกับการแปลงรูปแบบอื่น ๆ อัลกอริธึมที่ใช้กริด / ตาข่าย, มอนติคาร์โล, ฯลฯ หากคุณดูตัวอย่างโค้ด NVIDIA SDK คุณสามารถเข้าใจถึงปัญหาที่ได้รับการกล่าวถึงเป็นส่วนใหญ่

ฉันคิดว่าคำตอบที่ให้คำแนะนำเพิ่มเติมคือคำถามที่ว่า 'ปัญหาอะไรที่ GPU ใช้ไม่ดีจริงๆ' ปัญหาส่วนใหญ่ที่ไม่ได้อยู่ในหมวดหมู่นี้สามารถใช้กับ GPU ได้ แต่บางคนก็พยายามมากกว่าคนอื่น

ปัญหาที่แผนที่ไม่ดีมักจะมีขนาดเล็กเกินไปหรือคาดเดาไม่ได้ ปัญหาขนาดเล็กมากขาดความขนานที่จำเป็นในการใช้เธรดทั้งหมดบน GPU และ / หรือสามารถใส่ลงในแคชระดับต่ำบน CPU เพื่อเพิ่มประสิทธิภาพของ CPU อย่างมาก ปัญหาที่คาดเดาไม่ได้มีสาขาที่มีความหมายมากเกินไปซึ่งสามารถป้องกันข้อมูลจากการสตรีมจากหน่วยความจำ GPU ไปยังคอร์ได้อย่างมีประสิทธิภาพหรือลดความขนานได้โดยแบ่งกระบวนทัศน์SIMD (ดูที่ ' divergent warps ') ตัวอย่างของปัญหาประเภทนี้ ได้แก่ :

  • อัลกอริธึมกราฟส่วนใหญ่ (คาดเดาไม่ได้มากเกินไปโดยเฉพาะในพื้นที่หน่วยความจำ)
  • พีชคณิตเชิงเส้นที่กระจัดกระจาย (แต่นี่ก็ไม่ดีกับซีพียูด้วย)
  • ปัญหาการประมวลผลสัญญาณขนาดเล็ก (เช่น FFT เล็กกว่า 1,000 คะแนนเป็นต้น)
  • ค้นหา
  • ประเภท

3
แต่ถึงกระนั้นโซลูชั่น GPU สำหรับปัญหา "คาดเดาไม่ได้" นั้นเป็นไปได้และในปัจจุบันโดยทั่วไปไม่เป็นไปได้อาจเพิ่มความสำคัญในอนาคต
leftaroundabout

6
ฉันต้องการเพิ่มสาขาลงในรายการตัวแบ่งประสิทธิภาพของ GPU คุณต้องการให้คุณ (หลายร้อยคน) ใช้คำสั่งเดียวกัน (ใน SIMD) เพื่อทำการคำนวณแบบขนานอย่างแท้จริง ตัวอย่างเช่นในการ์ด AMD หากมีคำสั่งใดไหลพบสาขาและจะต้องแตกต่าง - diverges wavefront ทั้งหมด (กลุ่มขนาน) ทั้งหมด หากหน่วยอื่นจาก wavefront ต้องไม่เบี่ยงเบน - พวกเขาจะต้องดำเนินการผ่านที่สอง นั่นคือสิ่งที่ maxhutch หมายถึงการคาดเดาได้
ยีราฟสีม่วง

2
@VioletGiraffe นั่นไม่จำเป็นต้องเป็นเรื่องจริง ใน CUDA (เช่นบน Nvidia GPUs) ความแตกต่างของสาขาจะส่งผลต่อวาร์ปปัจจุบันเท่านั้นซึ่งมีได้สูงสุด 32 เธรด warps ที่แตกต่างกันแม้ว่าจะใช้รหัสเดียวกัน แต่จะไม่ซิงโครนัสเว้นแต่จะซิงโครไนซ์อย่างชัดเจน (เช่นกับ__synchtreads())
Pedro

1
@Pedro: จริง แต่การแตกแขนงโดยทั่วไปนั้นส่งผลกระทบต่อประสิทธิภาพการทำงาน สำหรับรหัสประสิทธิภาพสูง (รหัส GPU ใดที่ไม่ใช่?) เกือบเป็นสิ่งสำคัญที่จะต้องคำนึงถึง
jvriesem

21

ปัญหาที่มีความเข้มเลขคณิตสูงและรูปแบบการเข้าถึงหน่วยความจำปกติมักจะง่าย (ier) เพื่อใช้กับ GPU และทำงานได้ดี

ปัญหาขั้นพื้นฐานในการมีรหัส GPU ที่มีประสิทธิภาพสูงคือคุณมีคอร์มากมายและคุณต้องการให้มันถูกใช้อย่างเต็มประสิทธิภาพเท่าที่จะเป็นไปได้ ปัญหาที่มีรูปแบบการเข้าถึงหน่วยความจำไม่สม่ำเสมอหรือไม่มีความเข้มเลขคณิตสูงทำให้เป็นเรื่องยาก: ไม่ว่าคุณจะใช้เวลานานในการสื่อสารผลลัพธ์หรือคุณใช้เวลานานในการดึงสิ่งต่าง ๆ จากหน่วยความจำ (ซึ่งช้า!) และไม่มีเวลาเพียงพอ แน่นอนว่าโอกาสในการเกิดพร้อมกันในรหัสของคุณนั้นมีความสำคัญต่อความสามารถในการใช้งานกับ GPU ได้เป็นอย่างดี


คุณสามารถระบุความหมายของรูปแบบการเข้าถึงหน่วยความจำปกติได้หรือไม่?
Fomite

1
คำตอบของ maxhutch ดีกว่าของฉัน สิ่งที่ฉันหมายถึงโดยรูปแบบการเข้าถึงปกติคือการเข้าถึงหน่วยความจำในลักษณะชั่วคราวและเชิงพื้นที่ นั่นคือ: คุณไม่ได้กระโดดขนาดใหญ่รอบ ๆ หน่วยความจำซ้ำ ๆ มันเป็นเรื่องของแพ็คเกจที่ฉันสังเกตเห็น นอกจากนี้ยังหมายถึงว่ารูปแบบการเข้าถึงข้อมูลของคุณสามารถกำหนดไว้ล่วงหน้าโดยคอมไพเลอร์อย่างใดอย่างหนึ่งหรือโดยคุณโปรแกรมเมอร์เพื่อให้การแยกสาขา (งบเงื่อนไขในรหัส) ลดลง
Reid.Atcheson

15

นี้ไม่ได้ตั้งใจเป็นคำตอบในตัวเอง แต่นอกเหนือไปจากคำตอบอื่น ๆ โดยmaxhutchและReid.Atcheson

เพื่อให้ได้ประสิทธิภาพที่ดีที่สุดของ GPU ปัญหาของคุณไม่เพียง แต่จะต้องขนานกันอย่างมาก (หรือหนาแน่น) แต่ยังต้องใช้อัลกอริธึมหลักที่จะใช้กับ GPU ด้วยเช่นกัน ในOpenCLแง่นี้ส่วนใหญ่จะเรียกว่าเป็นเคอร์เนล

เพื่อให้แม่นยำยิ่งขึ้นเคอร์เนลควรจะพอดีกับการลงทะเบียนของแต่ละหน่วยประมวลผลหลายตัว (หรือหน่วยคำนวณ ) ของ GPU ขนาดที่แน่นอนของการลงทะเบียนขึ้นอยู่กับ GPU

เนื่องจากเคอร์เนลมีขนาดเล็กพอข้อมูลดิบของปัญหาจำเป็นต้องพอดีกับหน่วยความจำภายในของ GPU (อ่าน: หน่วยความจำภายใน (OpenCL) หรือหน่วยความจำแบบแบ่งใช้ (CUDA) ของหน่วยประมวลผล) มิฉะนั้นแม้แต่แบนด์วิดท์หน่วยความจำสูงของ GPU ก็ไม่เร็วพอที่จะทำให้องค์ประกอบการประมวลผลไม่ว่างตลอดเวลา
โดยปกติหน่วยความจำนี้เป็นเรื่องเกี่ยวกับ 16-32 KiByte ใหญ่


หน่วยความจำโลคอล / แชร์ของหน่วยการประมวลผลแต่ละหน่วยไม่ใช้ร่วมกันกับหลายสิบ (?) ของเธรดที่ทำงานภายในคอร์คลัสเตอร์เดียวใช่ไหม ในกรณีนี้คุณไม่จำเป็นต้องเก็บชุดการทำงานของคุณให้เล็กลงอย่างมีนัยสำคัญเพื่อที่จะได้ประสิทธิภาพสูงสุดจาก GPU หรือไม่?
Dan Neely

หน่วยความจำภายใน / ที่ใช้ร่วมกันของหน่วยการประมวลผลนั้นสามารถเข้าถึงได้โดยหน่วยการคำนวณเท่านั้นและจะถูกแชร์โดยองค์ประกอบการประมวลผลของหน่วยการประมวลผลนี้เท่านั้น หน่วยความจำร่วมของการ์ดกราฟิก (ปกติคือ 1GB) สามารถเข้าถึงได้โดยหน่วยประมวลผลทั้งหมด แบนด์วิดท์ระหว่างองค์ประกอบการประมวลผลและหน่วยความจำภายใน / ที่ใช้ร่วมกันนั้นรวดเร็วมาก (> 1TB / s) แต่แบนด์วิดท์ของหน่วยความจำทั่วโลกนั้นช้ากว่ามาก (~ 100GB / s) และจะต้องใช้ร่วมกันระหว่างหน่วยคำนวณทั้งหมด
Torbjörn

ฉันไม่ได้ถามเกี่ยวกับหน่วยความจำ GPU หลัก ฉันคิดว่าหน่วยความจำแบบ on ได้รับการจัดสรรให้กับคลัสเตอร์ของระดับคอร์ไม่ใช่เฉพาะคอร์แต่ละตัว เช่น nVidia GF100 / 110 gpu สำหรับ 16 SM แต่ละคลัสเตอร์ไม่ใช่ 512 cuda cores ด้วย SM แต่ละตัวที่ออกแบบมาให้ทำงานได้ถึง 32 เธรดในการเพิ่มประสิทธิภาพ GPU แบบขนานจะต้องทำให้ชุดการทำงานอยู่ในช่วง 1kb / เธรด
Dan Neely

@Trainjoern สิ่งที่คุณต้องการคือการทำให้การประมวลผล GPU ไม่ว่างท่อ GPU ทำได้สองวิธี: (1) วิธีที่พบมากที่สุดคือการเพิ่มจำนวนผู้เข้าพักหรือพูดต่างกันโดยเพิ่มจำนวนเธรดพร้อมกัน (เมล็ดขนาดเล็กใช้น้อยกว่า ทรัพยากรที่ใช้ร่วมกันเพื่อให้คุณสามารถมีเธรดที่ใช้งานได้มากขึ้น); อาจจะดีกว่าคือ (2) เพิ่มความเท่าเทียมในระดับคำสั่งภายในเคอร์เนลของคุณดังนั้นคุณสามารถมีเคอร์เนลขนาดใหญ่ที่มีอัตราการเข้าพักค่อนข้างต่ำ (จำนวนเธรดที่แอ็คทีฟจำนวนน้อย) ดูbit.ly/Q3KdI0
fcruz

11

อาจเป็นการเพิ่มเติมทางเทคนิคเพิ่มเติมสำหรับการตอบกลับก่อนหน้านี้: CUDA (เช่น Nvidia) GPU สามารถอธิบายได้ว่าเป็นชุดของโปรเซสเซอร์ที่ทำงานแบบอัตโนมัติในแต่ละ 32 เธรด เธรดในโปรเซสเซอร์แต่ละตัวทำงานในขั้นตอนการล็อก (คิดว่า SIMD กับเวกเตอร์ที่มีความยาว 32)

แม้ว่าวิธีที่ดึงดูดใจมากที่สุดในการทำงานกับ GPU คือการแกล้งทำเป็นว่าทุกอย่างทำงานในขั้นตอนล็อค แต่นี่ไม่ใช่วิธีที่มีประสิทธิภาพที่สุดในการทำสิ่งต่าง ๆ เสมอไป

หากโค้ดของคุณไม่ได้ขนานกัน / โดยอัตโนมัติเป็นร้อย / พันของเธรดคุณอาจสามารถแยกมันออกเป็นงานอะซิงโครนัสแต่ละตัวที่ทำงานแบบขนานได้ดี CUDA จัดเตรียมชุดของคำสั่งอะตอมมิกซึ่งทำให้สามารถนำmutexesไปใช้ซึ่งทำให้โปรเซสเซอร์สามารถซิงโครไนซ์กันเองและประมวลผลรายการงานในกระบวนทัศน์พูลเธรด รหัสของคุณจะทำงานในลักษณะเดียวกับที่ทำในระบบมัลติคอร์เพียงจำไว้ว่าแต่ละคอร์นั้นมี 32 เธรดของตัวเอง

นี่คือตัวอย่างเล็ก ๆ โดยใช้ CUDA ของวิธีการทำงาน

/* Global index of the next available task, assume this has been set to
   zero before spawning the kernel. */
__device__ int next_task;

/* We will use this value as our mutex variable. Assume it has been set to
   zero before spawning the kernel. */
__device__ int tasks_mutex;

/* Mutex routines using atomic compare-and-set. */
__device__ inline void cuda_mutex_lock ( int *m ) {
    while ( atomicCAS( m , 0 , 1 ) != 0 );
    }
__device__ inline void cuda_mutex_unlock ( int *m ) {
    atomicExch( m , 0 );
    }

__device__ void task_do ( struct task *t ) {

    /* Do whatever needs to be done for the task t using the 32 threads of
       a single warp. */
    }

__global__ void main ( struct task *tasks , int nr_tasks ) {

    __shared__ task_id;

    /* Main task loop... */
    while ( next_task < nr_tasks ) {

        /* The first thread in this block is responsible for picking-up a task. */
        if ( threadIdx.x == 0 ) {

            /* Get a hold of the task mutex. */
            cuda_mutex_lock( &tasks_mutex );

            /* Store the next task in the shared task_id variable so that all
               threads in this warp can see it. */
            task_id = next_task;

            /* Increase the task counter. */
            next_tast += 1;

            /* Make sure those last two writes to local and global memory can
               be seen by everybody. */
            __threadfence();

            /* Unlock the task mutex. */
            cuda_mutex_unlock( &tasks_mutex );

            }

        /* As of here, all threads in this warp are back in sync, so if we
           got a valid task, perform it. */
        if ( task_id < nr_tasks )
            task_do( &tasks[ task_id ] );

        } /* main loop. */

    }

จากนั้นคุณต้องเรียกเคอร์เนลด้วยmain<<<N,32>>>(tasks,nr_tasks)เพื่อให้แน่ใจว่าแต่ละบล็อกมีเพียง 32 เธรดและเหมาะกับการแปรปรวนเดี่ยว ในตัวอย่างนี้ฉันยังสันนิษฐานว่าเพื่อความเรียบง่ายว่างานไม่มีการอ้างอิงใด ๆ (เช่นงานหนึ่งขึ้นอยู่กับผลลัพธ์ของงานอื่น) หรือความขัดแย้ง (เช่นทำงานในหน่วยความจำระดับโลกเดียวกัน) หากเป็นกรณีนี้การเลือกงานจะซับซ้อนขึ้นเล็กน้อย แต่โครงสร้างนั้นเหมือนกัน

แน่นอนว่านี่ซับซ้อนกว่าการทำทุกอย่างในเซลล์จำนวนมาก แต่จะขยายประเภทของปัญหาที่สามารถใช้ GPU ได้อย่างมีนัยสำคัญ


2
นี่เป็นความจริงทางเทคนิค แต่ต้องการการขนานที่สูงเพื่อให้ได้แบนด์วิดท์หน่วยความจำสูงและมีการ จำกัด จำนวนการเรียกเคอร์เนลแบบอะซิงโครนัส (ปัจจุบัน 16) พวกเขายังเป็นพฤติกรรมที่ไม่มีเอกสารมากมายที่เกี่ยวข้องกับการกำหนดตารางเวลาในรีลีสปัจจุบัน ฉันแนะนำไม่ให้ใช้เมล็ดอะซิงโครนัสเพื่อเพิ่มประสิทธิภาพในขณะนี้ ...
Max Hutchinson

2
สิ่งที่ฉันอธิบายสามารถทำได้ทั้งหมดในการเรียกเคอร์เนลเดียว คุณสามารถสร้าง N บล็อกของ 32 เธรดแต่ละรายการได้เช่นกันซึ่งแต่ละบล็อกมีขนาดพอดี จากนั้นแต่ละบล็อกจะรับภารกิจจากรายการงานส่วนกลาง (การควบคุมการเข้าถึงโดยใช้ atomics / mutexes) และคำนวณโดยใช้ 32 เธรดที่ล็อก ทั้งหมดนี้เกิดขึ้นในการเรียกเคอร์เนลเดียว หากคุณต้องการตัวอย่างรหัสแจ้งให้เราทราบและฉันจะโพสต์หนึ่ง
Pedro

4

จุดหนึ่งที่ไม่สามารถทำได้คือการสร้าง GPU ในปัจจุบันไม่สามารถทำได้ด้วยการคำนวณจุดลอยตัวที่มีความแม่นยำสองเท่าเช่นเดียวกับการคำนวณที่มีความแม่นยำเดียว หากการคำนวณของคุณต้องดำเนินการด้วยความแม่นยำสองเท่าคุณสามารถคาดหวังว่าเวลาทำงานจะเพิ่มขึ้น 10 เท่าหรือมากกว่านั้นด้วยความแม่นยำเดียว


ฉันไม่เห็นด้วย GPU รุ่นใหม่ส่วนใหญ่ (หรือทั้งหมด) นั้นรองรับความแม่นยำสองเท่าแบบดั้งเดิม เกือบทุก GPU ดังกล่าวรายงานการคำนวณความแม่นยำสองเท่าที่ทำงานที่ความเร็วประมาณครึ่งเดียวของความแม่นยำอาจเกิดจากการเข้าถึงหน่วยความจำ / แบนด์วิดท์ที่ต้องการได้ง่ายขึ้นสองเท่า
Godric Seer

1
แม้ว่าจะเป็นความจริงที่ว่าการ์ด Nvidia Tesla ล่าสุดและยิ่งใหญ่ที่สุดมอบประสิทธิภาพความแม่นยำสูงสุดสองเท่าซึ่งเป็นครึ่งหนึ่งของประสิทธิภาพความแม่นยำสูงสุดเพียงครั้งเดียวอัตราส่วนคือ 8 ต่อ 1 สำหรับการ์ดเกรดผู้บริโภคสถาปัตยกรรม Fermi ทั่วไป
Brian Borchers

@GodricSeer อัตราส่วน 2: 1 ของ SP และ DP จำนวนจุดลอยตัวมีน้อยมากที่เกี่ยวข้องกับแบนด์วิดท์และแทบทุกอย่างเกี่ยวกับจำนวนหน่วยฮาร์ดแวร์ที่มีอยู่เพื่อดำเนินการการดำเนินการเหล่านี้ เป็นเรื่องปกติที่จะใช้ไฟล์ register ซ้ำสำหรับ SP และ DP ดังนั้นหน่วย floating-point สามารถเรียกใช้ SP ops เป็น 2x ops ได้ มีข้อยกเว้นมากมายสำหรับการออกแบบนี้เช่น IBM Blue Gene / Q (ไม่มีตรรกะ SP และทำให้ SP ทำงานที่ ~ 1.05x DP) GPU บางตัวมีอัตราส่วนอื่นที่ไม่ใช่ 2 เช่น 3 และ 5
Jeff

เป็นเวลาสี่ปีแล้วที่ฉันเขียนคำตอบนี้และสถานการณ์ปัจจุบันของ NVIDIA GPU คือสำหรับสาย GeForce และ Quadro ตอนนี้อัตราส่วน DP / SP ตอนนี้ 1/32 Tesla GPUs ของ NVIDIA นั้นมีประสิทธิภาพความแม่นยำสองเท่าที่แข็งแกร่งกว่า แต่ก็คุ้มค่ากว่าเช่นกัน ในทางตรงกันข้ามเอเอ็มดียังไม่ได้เพิ่มประสิทธิภาพการทำงานที่แม่นยำเป็นสองเท่าของ Radeon GPU ในลักษณะเดียวกัน
Brian Borchers

4

จากมุมมองเชิงเปรียบเทียบนั้น GPU สามารถมองได้ว่าเป็นคนที่นอนอยู่บนเตียงของเล็บ คนที่อยู่ด้านบนคือข้อมูลและที่ฐานของเล็บแต่ละอันมีโปรเซสเซอร์ดังนั้นเล็บจึงเป็นลูกศรชี้จากโปรเซสเซอร์ไปยังหน่วยความจำ เล็บทั้งหมดอยู่ในรูปแบบปกติเช่นตาราง หากร่างกายแพร่กระจายได้ดีก็รู้สึกดี (ประสิทธิภาพดี) หากร่างกายสัมผัสเพียงจุดเล็บบางจุดความเจ็บปวดนั้นไม่ดี (ประสิทธิภาพไม่ดี)

นี่อาจเป็นคำตอบที่สมบูรณ์สำหรับคำตอบที่ดีเลิศข้างต้น


4

คำถามเก่า แต่ฉันคิดว่าคำตอบนี้จาก 2014 - เกี่ยวข้องกับวิธีการทางสถิติ แต่โดยทั่วไปสำหรับใครที่รู้ว่าวงคืออะไร - เป็นตัวอย่างและให้ข้อมูลโดยเฉพาะ


2

GPU มีเวลาแฝงที่ยาวนาน I / O ดังนั้นจึงจำเป็นต้องใช้เธรดจำนวนมากเพื่อทำให้หน่วยความจำอิ่มตัว เพื่อให้ warp ไม่ว่างต้องใช้เธรดจำนวนมาก หากเส้นทางของรหัสคือ 10 นาฬิกาและเวลา I / O แฝง 320 นาฬิกา 32 เธรดควรเข้าใกล้กับการแปรปรวนแบบอิ่มตัว หากพา ธ ของรหัสคือ 5 นาฬิกาให้เพิ่มจำนวนเธรดเป็นสองเท่า

ด้วยหนึ่งพันคอร์มองหาเธรดนับพันเพื่อใช้ GPU อย่างเต็มที่

การเข้าถึงหน่วยความจำคือตามบรรทัดแคชโดยทั่วไปคือ 32 ไบต์ การโหลดหนึ่งไบต์มีราคาใกล้เคียงกับ 32 ไบต์ ดังนั้นรวมหน่วยเก็บข้อมูลเพื่อเพิ่มตำแหน่งการใช้งาน

มีรีจิสเตอร์และ RAM ท้องถิ่นจำนวนมากสำหรับแต่ละวิปริตทำให้สามารถแบ่งปันเพื่อนบ้านได้

การจำลองความใกล้เคียงของชุดขนาดใหญ่ควรปรับให้เหมาะสมดี

I / O แบบสุ่มและเธรดเดี่ยวเป็นความสุขที่ฆ่า ...


นี่เป็นคำถามที่น่าสนใจอย่างแท้จริง ฉันโต้เถียงกับตัวเองว่าเป็นไปได้ (หรือคุ้มค่ากับความพยายาม) ในการ 'parallel-ise' เป็นงานที่ตรงไปตรงมาอย่างสมเหตุสมผล (การตรวจจับขอบในภาพถ่ายทางอากาศ) เมื่อแต่ละงานใช้เวลา ~ 0.06sec แต่มีประมาณ 1.8 ล้านงาน ต่อปีสำหรับข้อมูลมูลค่า 6 ปี: ภาระงานแบ่งออกได้อย่างแน่นอน) ... ดังนั้นเวลาในการคำนวณประมาณ 7.5 วันบนแกนหลักเดียว หากการคำนวณแต่ละอันเร็วขึ้นบน GPU และงานสามารถขนานกันได้ 1 ต่อ nGPUcores [เล็ก ๆ น้อย ๆ ] เป็นไปได้หรือไม่ที่จริงแล้วเวลาในการทำงานลดลงเหลือ ~ 1 ชั่วโมงหรือไม่? ดูเหมือนว่าไม่น่า
GT

0

ลองนึกภาพปัญหาที่สามารถแก้ไขได้ด้วยกำลังดุร้ายมากมายเช่นพนักงานขายนักท่องเที่ยว จากนั้นลองจินตนาการว่าคุณมีแร็คของเซิร์ฟเวอร์ที่มีการ์ดวิดีโอ 8 อันแต่ละอันมีการ์ด 3000 CUDA แกน

เพียงแก้ไขเส้นทางของพนักงานขายที่เป็นไปได้ทั้งหมดแล้วเรียงลำดับเวลา / ระยะทาง / ตัวชี้วัดบางอย่าง แน่นอนว่าคุณกำลังทิ้งงานเกือบ 100% ของคุณ แต่บางครั้งแรงเดรัจฉานก็เป็นทางออกที่เหมาะสม


ฉันได้เข้าถึงฟาร์มขนาดเล็กของเซิร์ฟเวอร์ดังกล่าว 4 แห่งเป็นเวลาหนึ่งสัปดาห์และในอีกห้าวันฉันได้แจกจ่ายบล็อก.netมากกว่าช่วง 10 ปีที่ผ่านมา
Criggie

-1

จากการศึกษาแนวคิดทางวิศวกรรมมากมายฉันจะบอกว่า gpu เป็นรูปแบบของการมุ่งเน้นงานการจัดการหน่วยความจำการคำนวณซ้ำ

สูตรหลายสูตรอาจเขียนง่าย แต่เจ็บปวดในการคำนวณเช่นในคณิตศาสตร์เมทริกซ์คุณไม่ได้รับคำตอบเดียว แต่มีค่ามากมาย

สิ่งนี้มีความสำคัญในการคำนวณว่าคอมพิวเตอร์คำนวณค่าและสูตรการรันได้เร็วแค่ไหนเนื่องจากสูตรบางสูตรไม่สามารถทำงานได้หากไม่มีค่าที่คำนวณได้ทั้งหมด (ช้าลง) คอมพิวเตอร์ไม่ทราบว่าจะเรียกใช้สูตรหรือคำนวณค่าที่ใช้ในโปรแกรมเหล่านี้ได้ดีเพียงใด โดยส่วนใหญ่มันจะดุร้ายด้วยความเร็วที่รวดเร็วและแบ่งสูตรออกเป็น chucks เพื่อคำนวณ แต่หลาย ๆ โปรแกรมในปัจจุบันต้องใช้ chucks ที่คำนวณได้ในตอนนี้และรอเป็น ques (และ ques ของ ques และ ques อื่น ๆ ของ ques)

ตัวอย่างเช่นในเกมจำลองสถานการณ์ที่ควรคำนวณเป็นอันดับแรกในการชนกันของความเสียหายของการชนตำแหน่งของวัตถุความเร็วใหม่? ควรใช้เวลาเท่าไหร่? ซีพียูใด ๆ สามารถจัดการกับโหลดนี้ได้อย่างไร? นอกจากนี้โปรแกรมส่วนใหญ่เป็นนามธรรมมากต้องใช้เวลามากขึ้นในการจัดการข้อมูลและไม่ได้รับการออกแบบมาสำหรับหลายเธรดหรือไม่ใช่วิธีที่ดีในโปรแกรมนามธรรมเพื่อทำสิ่งนี้ได้อย่างมีประสิทธิภาพ

เมื่อซีพียูดีขึ้นและคนดีขึ้นก็กลายเป็นคนเขียนโปรแกรมและเราต้องตั้งโปรแกรมสำหรับคอมพิวเตอร์หลายประเภทด้วยเช่นกัน gpu ถูกออกแบบมาเพื่อเดรัจฉานแรงผ่านการคำนวณแบบง่าย ๆ จำนวนมากในเวลาเดียวกัน (ไม่พูดถึงหน่วยความจำ (รอง / ram) และการระบายความร้อนเป็นคอขวดหลักในการคำนวณ) ซีพียูมีการจัดการ ques จำนวนมากในเวลาเดียวกันหรือถูกดึงไปในหลาย ๆ ทิศทางมันกำลังหาสิ่งที่ไม่สามารถทำได้ (เฮ้มันเกือบจะเป็นมนุษย์)

GPU เป็นคนที่ทำเสียงฮึดฮัดแสดงความไม่พอใจ ซีพียูกำลังจัดการกับความโกลาหลอย่างสมบูรณ์และไม่สามารถจัดการได้ทุกรายละเอียด

แล้วเราเรียนรู้อะไร gpu ทำงานรายละเอียดที่น่าเบื่อได้ในคราวเดียวและ cpu เป็นเครื่องที่ทำงานหลายอย่างที่ไม่สามารถโฟกัสได้ดีกับงานที่ต้องทำมากเกินไป (มันเหมือนว่ามันมีความสนใจและออทิสติกในเวลาเดียวกัน)

วิศวกรรมมีความคิดการออกแบบความเป็นจริงและงานหนัก

ในขณะที่ฉันจำไว้ว่าให้เริ่มง่ายๆให้เริ่มอย่างรวดเร็วล้มเหลวเร็วล้มเหลวเร็วและไม่หยุดพยายาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.