ความรู้เบื้องต้น
- C – programing
- OpenMP
การเขียนโปรแกรมบนสถาปัตยกรรม shared momory ปัญหาหนึ่งที่เรามักจะพบคือ race condition หรือ “ภาวะแข่งขัน” ยกตัวอย่าง การเขียนโปรแกรมด้วย OpenMP ในลักษณะนี้นะครับ
1: int i=0;
2: #pragma omp parallel
3: i++;
4: printf(“%3d”,i);
โค๊ดนี้ผมนำไปรันบน intel processor แบบ quad core ปรากฏว่าผลลัพธ์ให้ค่าที่เหวี่ยงไปมา ตัวอย่าง ผลลัพธ์ของเครื่องผม 20 รอบคำสั่งคือ
3 3 4 3 4 3 3 4 4 4 4 4 3 2 4 3 3 3 4 4
บรรทัดที่ 3 ของโปรแกรม เกิด race condition ขึ้น เนื่องจากตัวแปร i เป็นตัวแปรที่ใช้ร่วมกัน สำหรับ thread ทั้ง 4 ตัว ดังนั้นจังหวะที่อ่านและเขียนข้อมูลถ้าไม่มีลักษะเป็น atomic จะทำให้เกิดปัญหานี้ขึ้นได้
OpenMP มี directive ชื่อว่า atomic สำหรับช่วยให้ thread ใดๆ สามารถอัปเดตของตัวแปรใด ๆ ได้โดยที่ไม่ต้องกังวลว่า ณ เวลานั้นจะมี thread ตัวอื่นเข้ามาเรียกใช้งาน ดังนั้นจากตัวอย่างข้างบนเราสามารถแก้ไขโดยใช้ atomic ได้ดังนี้
1: int i=0;
2: #pragma omp parallel
3: {
4: #pragma omp atomic
5: i++;
6: }
7: printf(“%3d”,i);
ผลลัพธ์ 20 รอบคำสั่ง เมื่อแก้ไขโปรแกรมแล้ว
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
สำหรับ directive atomic นั้นไม่สามารถกำหนดให้ block ของ code ได้ ถ้าต้องการป้องกันตัวแปรมากกว่า 1 ตัว วิธีการหนึ่งคือ ต้องเขียน #pragma omp atomic ให้กับทุกๆตัวแปร ดังนี้
1: int i=0,j=0;
2: #pragma omp parallel
3: {
4: #pragma omp atomic
5: i++;
6: #pragma omp atomic
7: j++;
8: }
9: printf(“i=%d,j=%d\n”,i,j);
OpenMP มี directive อีกตัวหนึ่งที่ให้ใช้ได้ง่ายกว่า คือ critical ซึ่งหน้าที่จะเหมือนกับ atomic เพียงแต่เราสามารถกำหนดส่วนของ block ลงไปได้เลย ซึ่งจะช่วยลดความยุ่งยากในการเขียนโปรแกรมไปได้พอสมควร
1: int i=0,j=0;
2: #pragma omp parallel
3: {
4: #pragma omp critical
5: {
6: i++;
7: j++;
8: }
9: }
10: printf(“i=%d,j=%d\n”,i);
ใส่ความเห็น