กอล์ฟนี้ต้องการการคำนวณแบบแฟคทอเรียลแยกเป็นหลายกลุ่มหรือหลายกระบวนการ
บางภาษาทำให้การประสานงานนี้ง่ายกว่าภาษาอื่นดังนั้นจึงเป็นภาษาที่ไม่เชื่อเรื่องพระเจ้า มีการจัดเตรียมโค้ดตัวอย่างที่ไม่ได้รับการปรุงแต่ง แต่คุณควรพัฒนาอัลกอริทึมของคุณเอง
เป้าหมายของการแข่งขันคือการดูว่าใครสามารถเกิดอัลกอริธึมมัลติคอร์แฟคทอเรียลที่สั้นที่สุด (เป็นไบต์ไม่กี่วินาที) สำหรับการคำนวณ N! วัดจากคะแนนโหวตเมื่อการประกวดปิด ควรมีข้อได้เปรียบแบบมัลติคอร์ดังนั้นเราจึงต้องการให้ใช้งานได้กับ N ~ 10,000 ผู้ลงคะแนนควรออกเสียงลงคะแนนหากผู้เขียนไม่สามารถให้คำอธิบายที่ถูกต้องเกี่ยวกับวิธีการเผยแพร่งานระหว่างโปรเซสเซอร์ / คอร์และลงคะแนนตามความกระชับของกอล์ฟ
สำหรับความอยากรู้อยากเห็นกรุณาโพสต์ตัวเลขประสิทธิภาพบางอย่าง อาจมีคะแนนการปฏิบัติงานเทียบกับการแลกเปลี่ยนคะแนนของกอล์ฟในบางประเด็นไปกับการเล่นกอล์ฟตราบใดที่ตรงตามความต้องการ ฉันอยากรู้ว่าจะเกิดอะไรขึ้น
คุณสามารถใช้ไลบรารีจำนวนเต็มแกนเดี่ยวขนาดใหญ่ที่มีอยู่ตามปกติ ตัวอย่างเช่น Perl มักจะติดตั้งด้วย bigint อย่างไรก็ตามโปรดทราบว่าเพียงแค่เรียกระบบที่มีฟังก์ชั่นแฟกทอเรียลจะไม่แยกงานออกเป็นหลายคอร์
คุณต้องยอมรับจาก STDIN หรือ ARGV อินพุต N และเอาต์พุตเพื่อ STDOUT ค่า N! คุณอาจเลือกใช้พารามิเตอร์อินพุตลำดับที่ 2 เพื่อระบุจำนวนตัวประมวลผล / แกนประมวลผลให้กับโปรแกรมดังนั้นจึงไม่ทำสิ่งที่คุณเห็นด้านล่าง :-) หรือคุณอาจออกแบบอย่างชัดเจนสำหรับ 2, 4 สิ่งที่คุณมีอยู่
ผมจะโพสต์ตัวอย่างลูกบอลในกอล์ฟ Perl ของตัวเองด้านล่างส่งมาก่อนหน้านี้ในกองมากเกินภายใต้ปัจจัยอัลกอริทึมในต่างภาษา มันไม่ใช่กอล์ฟ ตัวอย่างอื่น ๆ อีกมากมายถูกส่งหลายคนกอล์ฟ แต่หลายคนไม่ได้ เนื่องจากการให้สิทธิ์ใช้งานแบบแบ่งใช้เหมือนกันคุณสามารถใช้รหัสในตัวอย่างใด ๆ ในลิงก์ด้านบนเป็นจุดเริ่มต้น
ประสิทธิภาพในตัวอย่างของฉันนั้นไม่ค่อยสดใสนักด้วยเหตุผลหลายประการ: มันใช้กระบวนการมากเกินไปการแปลงสตริง / bigint มากเกินไป อย่างที่ฉันบอกว่ามันเป็นตัวอย่างที่ผิดพลาดอย่างจงใจ มันจะคำนวณ 5,000! ภายใน 10 วินาทีบนเครื่อง 4 คอร์ที่นี่ อย่างไรก็ตามการซับสองครั้งที่ชัดเจนสำหรับ / loop ถัดไปสามารถทำได้ 5,000! บนหนึ่งในสี่โปรเซสเซอร์ใน 3.6s
คุณจะต้องทำดีกว่านี้อย่างแน่นอน:
#!/usr/bin/perl -w
use strict;
use bigint;
die "usage: f.perl N (outputs N!)" unless ($ARGV[0] > 1);
print STDOUT &main::rangeProduct(1,$ARGV[0])."\n";
sub main::rangeProduct {
my($l, $h) = @_;
return $l if ($l==$h);
return $l*$h if ($l==($h-1));
# arghhh - multiplying more than 2 numbers at a time is too much work
# find the midpoint and split the work up :-)
my $m = int(($h+$l)/2);
my $pid = open(my $KID, "-|");
if ($pid){ # parent
my $X = &main::rangeProduct($l,$m);
my $Y = <$KID>;
chomp($Y);
close($KID);
die "kid failed" unless defined $Y;
return $X*$Y;
} else {
# kid
print STDOUT &main::rangeProduct($m+1,$h)."\n";
exit(0);
}
}
ความสนใจของฉันในเรื่องนี้คือ (1) บรรเทาความเบื่อหน่าย; และ (2) เรียนรู้สิ่งใหม่ นี่ไม่ใช่การบ้านหรือปัญหาการวิจัยสำหรับฉัน
โชคดี!
