แยกแฟกทอเรียล


12

กอล์ฟนี้ต้องการการคำนวณแบบแฟคทอเรียลแยกเป็นหลายกลุ่มหรือหลายกระบวนการ

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

เป้าหมายของการแข่งขันคือการดูว่าใครสามารถเกิดอัลกอริธึมมัลติคอร์แฟคทอเรียลที่สั้นที่สุด (เป็นไบต์ไม่กี่วินาที) สำหรับการคำนวณ 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) เรียนรู้สิ่งใหม่ นี่ไม่ใช่การบ้านหรือปัญหาการวิจัยสำหรับฉัน

โชคดี!


10
คุณไม่สามารถนับรหัสที่สั้นที่สุดด้วยการลงคะแนนและความต้องการเล่นกอล์ฟและแบบมัลติเธรดดูเหมือนจะแย่ไปด้วยกัน
aaaaaaaaaaaa

โน้ตบุ๊คแกนเดี่ยวโบราณของฉันสามารถทำ 10,000! ในน้อยกว่า 0.2 วินาทีใน Python
gnibbler

การทำเธรดแบบหลายเธรดที่ผูกกับ CPU จะทำให้ช้าลงเกือบตลอดเวลา สิ่งที่คุณกำลังทำคือการเพิ่มค่าใช้จ่ายที่มีประสิทธิภาพน้อยหรือไม่มีเลย มัลติเธรดใช้สำหรับ I / O-wait
mellamokb

2
@mellamokb: ฉันขอแตกต่างกันสำหรับระบบมัลติคอร์
Joey

@Joey: อ่า พลาดรายละเอียดเล็กน้อยนั้น: เห็นด้วย
mellamokb

คำตอบ:


7

มาติกา

ฟังก์ชั่นที่สามารถใช้งานได้แบบขนาน:

 f[n_, g_] := g[Product[N@i, {i, 1, n, 2}] Product[N@i, {i, 2, n, 2}]]

ที่ไหนกรัมIdentityหรือParallelizeขึ้นอยู่กับชนิดของกระบวนการที่จำเป็น

สำหรับการทดสอบเวลาเราจะปรับเปลี่ยนฟังก์ชั่นเล็กน้อยดังนั้นมันจะคืนค่าเวลานาฬิกาจริง

f[n_, g_] := First@AbsoluteTiming[g[Product[N@i,{i,1,n,2}] Product[N@i,{i,2,n,2}]]]

และเราทดสอบทั้งสองโหมด (จาก 10 ^ 5 สูงสุด 9 * 10 ^ 5): (เฉพาะที่นี่สองเมล็ด)

ListLinePlot[{Table[f[i, Identity],    {i, 100000, 900000, 100000}], 
              Table[f[i, Parallelize], {i, 100000, 900000, 100000}]}]   

ผลลัพธ์: ป้อนคำอธิบายรูปภาพที่นี่


คุณหายไป] ในบรรทัดรหัสแรกหรือไม่? มันดูไม่สมดุล
Peter Taylor

@Peter ขอบคุณสุดท้าย "]" ไม่ได้ผ่านการคัดลอกบัฟเฟอร์ การแก้ไข
ดร. เบลิซา

1
สิ่งนี้ดูเหมือนจะสั้นที่สุด ดูเหมือนว่าเร็วที่สุดเว้นแต่ฉันจะอ่านข้อความผิด ฉันไม่สมัครสมาชิก Mathematica ดังนั้นจึงไม่สามารถยืนยันได้ ขอบคุณสำหรับการเข้าร่วม
พอล

7

Haskell: 209 200 198 177 ตัวอักษร

176 167 source + 33 10 compiler flag

วิธีแก้ปัญหานี้ค่อนข้างงี่เง่า มันใช้ผลิตภัณฑ์แบบขนานกับค่าประเภท[[Integer]]ที่รายการด้านในมีความยาวไม่เกินสองรายการ เมื่อรายการภายนอกลงไปสูงสุด 2 รายการเราจะแบนและนำผลิตภัณฑ์โดยตรง และใช่ตัวตรวจสอบชนิดต้องการบางสิ่งที่มีคำอธิบายประกอบด้วยจำนวนเต็มมิฉะนั้นจะไม่สามารถรวบรวมได้

import Control.Parallel.Strategies
s(x:y:z)=[[x,y::Integer]]++s z;s x=[x]
p=product
f n=p$concat$(until((<3).length)$s.parMap rseq p)$s[1..n]
main=interact$show.f.read

(อย่าลังเลที่จะอ่านส่วนตรงกลางของfระหว่างconcatและsเป็น "จนกว่าฉันจะรักความยาว")

สิ่งที่ดูเหมือนว่าพวกเขาจะค่อนข้างดีตั้งแต่ parMap จาก Control.Parallel.Strategies ทำให้การทำฟาร์มนี้เป็นเรื่องง่าย อย่างไรก็ตามดูเหมือนว่า GHC 7 ต้องใช้ตัวเลือก 33 ตัวในบรรทัดคำสั่งและสภาพแวดล้อมของ vars เพื่อเปิดใช้งานจริงของเธรดรันไทม์เพื่อใช้หลายคอร์ (ซึ่งฉันรวมอยู่ในทั้งหมด) เว้นแต่ฉันจะพลาดบางสิ่งบางอย่างซึ่งเป็นไปได้ อย่างแน่นอนในกรณีนี้ ( อัปเดต : รันไทม์ GHC แบบเธรดดูเหมือนว่าจะใช้เธรด N-1 โดยที่ N คือจำนวนของคอร์ดังนั้นไม่จำเป็นต้องเล่นซอพร้อมกับตัวเลือกเวลาทำงาน)

เพื่อรวบรวม:

ghc -threaded prog.hs

รันไทม์ แต่ก็ค่อนข้างดีเมื่อพิจารณาจากจำนวนการประเมินแบบขนานที่ไร้สาระที่เกิดขึ้นและฉันไม่ได้รวบรวม -O2 สำหรับ 50,000! ใน MacBook แบบ dual-core ฉันได้รับ:

SPARKS: 50020 (29020 converted, 1925 pruned)

INIT  time    0.00s  (  0.00s elapsed)
MUT   time    0.20s  (  0.19s elapsed)
GC    time    0.12s  (  0.07s elapsed)
EXIT  time    0.00s  (  0.00s elapsed)
Total time    0.31s  (  0.27s elapsed)

เวลารวมสำหรับค่าที่แตกต่างกันสองสามคอลัมน์แรกคือขนาน golfed ที่สองคือรุ่นต่อเนื่องไร้เดียงสา:

          Parallel   Sequential
 10000!      0.03s        0.04s
 50000!      0.27s        0.78s
100000!      0.74s        3.08s
500000!      7.04s       86.51s

สำหรับการอ้างอิงรุ่นต่อเนื่องไร้เดียงสาคือสิ่งนี้ (ซึ่งถูกคอมไพล์ด้วย -O2):

factorial :: Integer -> Integer
factorial n = product [1..n]
main = interact $ show.factorial.read

1
IMO คุณไม่ต้องนับ args สำหรับคอมไพเลอร์และล่าม
FUZxxl

@FUZxxl: ปกติฉันจะเห็นด้วย แต่ปัญหานี้ขอโดยเฉพาะว่ามันทำงานในหลายกระทู้หรือกระบวนการและธงเหล่านั้นจะต้องทำให้เกิดขึ้น (กับ GHC 7.0.2 จากแพลตฟอร์ม Haskell ล่าสุดอย่างน้อย)

6

Ruby - 111 + 56 = 167 ตัวอักษร

นี่เป็นสคริปต์ไฟล์สองไฟล์คือไฟล์หลัก ( fact.rb):

c,n=*$*.map(&:to_i)
p=(0...c).map{|k|IO.popen("ruby f2.rb #{k} #{c} #{n}")}
p p.map{|l|l.read.to_i}.inject(:*)

ไฟล์พิเศษ ( f2.rb):

c,h,n=*$*.map(&:to_i)
p (c*n/h+1..(c+1)*n/h).inject(:*)

ใช้จำนวนกระบวนการและจำนวนในการคำนวณเป็น args และแบ่งการทำงานออกเป็นช่วงที่แต่ละกระบวนการสามารถคำนวณเป็นรายบุคคล จากนั้นคูณผลลัพธ์ในตอนท้าย

นี่แสดงให้เห็นว่า Rubinius ทำงานช้ากว่ามากเพียงใดเพื่อ YARV:

Rubinius:

time ruby fact.rb 5 5000 #=> 61.84s

Ruby1.9.2:

time ruby fact.rb 5 50000 #=> 3.09s

(หมายเหตุเพิ่มเติม0)


1
inject(:+)ฉีดสามารถใช้สัญลักษณ์เป็นอาร์กิวเมนต์เพื่อให้คุณสามารถบันทึกตัวอักษรโดยใช้ (5..10).reduce(:+)นี่คือตัวอย่างจากเอกสารนี้
Michael Kohl

@Michael: ขอบคุณ :) เพิ่งสังเกตว่าฉันมี8ที่ควรจะมี*ถ้าใครมีปัญหาในการใช้งาน
Nemo157

6

Java, 523 519 434 430 429 ตัวอักษร

import java.math.*;public class G extends Thread{BigInteger o,i,r=BigInteger.ONE,h;G g;G(BigInteger O,int
I,int n){o=O;i=new BigInteger(""+I);if(n>1)g=new G(O.subtract(r),I,n-1);h=n==I?i:r;start();}public void
run(){while(o.signum()>0){r=r.multiply(o);o=o.subtract(i);}try{g.join();r=r.multiply(g.r);}catch(Exception
e){}if(h==i)System.out.println(r);}public static void main(String[] args){new G(new BigInteger(args[0]),4,4);}}

4s สองตัวในบรรทัดสุดท้ายคือจำนวนเธรดที่ใช้

50000! ทดสอบกับเฟรมเวิร์กต่อไปนี้ (เวอร์ชันดั้งเดิมของเวอร์ชันที่ไม่ดีและมีการปฏิบัติที่ไม่ดีน้อยกว่าเล็กน้อย - ถึงแม้ว่ามันจะยังคงมีจำนวนมาก) ให้ (บนเครื่อง Linux แบบ 4 คอร์ของฉัน)

7685ms
2338ms
1361ms
1093ms
7724ms

โปรดทราบว่าฉันทำการทดสอบซ้ำโดยใช้หนึ่งเธรดเพื่อความเป็นธรรมเพราะ jit อาจอุ่นขึ้น

import java.math.*;

public class ForkingFactorials extends Thread { // Bad practice!
    private BigInteger off, inc;
    private volatile BigInteger res;

    private ForkingFactorials(int off, int inc) {
        this.off = new BigInteger(Integer.toString(off));
        this.inc = new BigInteger(Integer.toString(inc));
    }

    public void run() {
        BigInteger p = new BigInteger("1");
        while (off.signum() > 0) {
            p = p.multiply(off);
            off = off.subtract(inc);
        }
        res = p;
    }

    public static void main(String[] args) throws Exception {
        int n = Integer.parseInt(args[0]);
        System.out.println(f(n, 1));
        System.out.println(f(n, 2));
        System.out.println(f(n, 3));
        System.out.println(f(n, 4));
        System.out.println(f(n, 1));
    }

    private static BigInteger f(int n, int numThreads) throws Exception {
        long now = System.currentTimeMillis();
        ForkingFactorials[] th = new ForkingFactorials[numThreads];
        for (int i = 0; i < n && i < numThreads; i++) {
            th[i] = new ForkingFactorials(n-i, numThreads);
            th[i].start();
        }
        BigInteger f = new BigInteger("1");
        for (int i = 0; i < n && i < numThreads; i++) {
            th[i].join();
            f = f.multiply(th[i].res);
        }
        long t = System.currentTimeMillis() - now;
        System.err.println("Took " + t + "ms");
        return f;
    }
}

Java ที่มี bigints ไม่ใช่ภาษาที่เหมาะสมสำหรับการเล่นกอล์ฟ (ดูสิ่งที่ฉันต้องทำเพื่อสร้างสิ่งที่น่าสังเวชเพราะตัวสร้างที่ใช้เวลานานจะเป็นส่วนตัว) แต่เฮ้

มันควรจะชัดเจนจากโค้ด ungolfed อย่างชัดเจนว่ามันแบ่งงานอย่างไร: เธรดแต่ละตัวคูณคลาสที่เทียบเท่ากับโมดูโลตามจำนวนเธรด จุดสำคัญคือแต่ละเธรดทำงานในปริมาณที่เท่ากัน


5

CSharp - 206 215 ตัวอักษร

using System;using System.Numerics;using System.Threading.Tasks;class a{static void Main(){var n=int.Parse(Console.ReadLine());var r=new BigInteger(1);Parallel.For(1,n+1,i=>{lock(this)r*=i;});Console.WriteLine(r);}}

แยกการคำนวณด้วยฟังก์ชัน C # Parallel.For ()

แก้ไข; ลืมล็อค

เวลาดำเนินการ:

n = 10,000, time: 59ms.
n = 20,000, time: 50ms.
n = 30,000, time: 38ms.
n = 40,000, time: 100ms.
n = 50,000, time: 139ms.
n = 60,000, time: 164ms.
n = 70,000, time: 222ms.
n = 80,000, time: 266ms.
n = 90,000, time: 401ms.
n = 100,000, time: 424ms.
n = 110,000, time: 501ms.
n = 120,000, time: 583ms.
n = 130,000, time: 659ms.
n = 140,000, time: 832ms.
n = 150,000, time: 1143ms.
n = 160,000, time: 804ms.
n = 170,000, time: 653ms.
n = 180,000, time: 1031ms.
n = 190,000, time: 1034ms.
n = 200,000, time: 1765ms.
n = 210,000, time: 1059ms.
n = 220,000, time: 1214ms.
n = 230,000, time: 1362ms.
n = 240,000, time: 2737ms.
n = 250,000, time: 1761ms.
n = 260,000, time: 1823ms.
n = 270,000, time: 3357ms.
n = 280,000, time: 2110ms.

4

Perl, 140

ใช้Nจากอินพุตมาตรฐาน

use bigint;$m=<>;open A,'>',
undef;$i=$p=fork&&1;$n=++$i;
{$i+=2;$n*=$i,redo if$i<=$m}
if($p){wait;seek A,0,0;$_=<A
>;print$n*$_}else{print A$n}

คุณสมบัติ:

  • การแยกการคำนวณ: evens ในด้านหนึ่งและอัตราต่อรองในสิ่งอื่น ๆ (สิ่งที่ซับซ้อนกว่านั้นจะต้องมีอักขระจำนวนมากเพื่อปรับสมดุลภาระการคำนวณอย่างเหมาะสม
  • IPC ใช้ไฟล์ที่ไม่ระบุชื่อที่ใช้ร่วมกัน

เกณฑ์มาตรฐาน:

  • 10000! ถูกพิมพ์ใน 2.3s ทางแยก, ไม่ได้เปิด 3.4s
  • 100000! ถูกพิมพ์ใน 5'08.8 ที่มีการแยกส่วน, 7'07.9 ที่แยกออกมา

4

สกาลา ( 345 266 244 232 214 ตัวอักษร)

ใช้นักแสดง:

object F extends App{import actors.Actor._;var(t,c,r)=(args(1).toInt,self,1:BigInt);val n=args(0).toInt min t;for(i<-0 to n-1)actor{c!(i*t/n+1 to(i+1)*t/n).product};for(i<-1 to n)receive{case m:Int=>r*=m};print(r)}

แก้ไข - ลบการอ้างอิงถึงSystem.currentTimeMillis(), แยกตัวประกอบa(1).toInt, เปลี่ยนจากList.rangeเป็นx to y

แก้ไข 2 - เปลี่ยนwhileลูปเป็น a for, เปลี่ยนโฟลด์ซ้ายไปยังฟังก์ชั่นลิสต์ที่ทำสิ่งเดียวกันโดยอาศัยการแปลงประเภทโดยนัยดังนั้นBigIntประเภทchar 6 จะปรากฏเพียงครั้งเดียวเปลี่ยนการพิมพ์เพื่อพิมพ์

แก้ไข 3 - ค้นพบวิธีการประกาศหลายรายการใน Scala

แก้ไข 4 - การเพิ่มประสิทธิภาพต่างๆที่ฉันได้เรียนรู้ตั้งแต่ฉันทำสิ่งนี้เป็นครั้งแรก

เวอร์ชันที่ไม่ถูกปรับแต่ง:

import actors.Actor._
object ForkingFactorials extends App
{
    var (target,caller,result)=(args(1).toInt,self,1:BigInt)
    val numthreads=args(0).toInt min target
    for(i<-0 to numthreads-1)
        actor
        {
            caller ! (i*target/numthreads+1 to(i+1)*target/numthreads+1).product
        }
    for(i<-1 to numthreads)
        receive
        {
            case m:Int=>result*=m
        }
    print(result)
}

3

Scala-2.9.0 170

object P extends App{
def d(n:Int,c:Int)=(for(i<-1 to c)yield(i to n by c)).par
println((BigInt(1)/: d(args(0).toInt,args(1).toInt).map(x=>(BigInt(1)/: x)(_*_)))(_*_))}

ungolfed:

object ParallelFactorials extends App
{
  def distribute (n: Int, cores: Int) = {
    val factorgroup = for (i <- 1 to cores) 
      yield (i to n by cores)
    factorgroup.par
  }

  val parallellist = distribute (args(0).toInt, args(1).toInt)

  println ((BigInt (1) /: parallellist.map (x => (BigInt(1) /: x) (_ * _)))(_ * _))

}

แฟคทอเรียลของ 10 คำนวณจาก 4 แกนโดยสร้าง 4 รายการ:

  • 1 5 9
  • 2 6 10
  • 3 7
  • 4 8

ซึ่งถูกคูณในแบบคู่ขนาน จะมีวิธีการที่ง่ายกว่าในการกระจายตัวเลข:

 (1 to n).sliding ((n/cores), (n/cores) 
  • 1 2 3
  • 4 5 6
  • 7 8 9
  • 10

แต่การแจกแจงจะไม่ดีเท่านี้ - จำนวนที่น้อยกว่าจะจบลงในรายการเดียวกันมากที่สุดในอีกอันหนึ่งซึ่งนำไปสู่การคำนวณที่ยาวขึ้นในรายการสุดท้าย (สำหรับ Ns สูงหัวข้อสุดท้ายจะไม่ว่างเปล่า แต่อย่างน้อยมีองค์ประกอบ (N / แกน) -cores

Scala ในเวอร์ชั่น 2.9 มี Collections แบบขนานซึ่งจัดการการเรียกใช้แบบขนานเอง


2

Erlang - 295 ตัวอักษร

สิ่งแรกที่ฉันเคยเขียนใน Erlang ดังนั้นฉันจะไม่แปลกใจถ้ามีคนสามารถลดครึ่งนี้ได้อย่างง่ายดาย:

-module(f).
-export([m/2,f/4]).
m(N,C)->g(N,C,C,[]).
r([],B)->B;
r(A,B)->receive{F,V}->r(lists:delete(F,A),V*B)end.
s(H,L)->spawn(f,f,[self(),H,L,1]).
g(N,1,H,A)->r([s(N div H,1)|A],1);
g(N,C,H,A)->g(N,C-1,H,[s(N*C div H,N*(C-1) div H)|A]).
f(P,H,H,A)->P!{self(),A};
f(P,H,L,A)->f(P,H-1,L,A*H).

ใช้เธรดเดียวกับรายการ Ruby รุ่นก่อนหน้าของฉัน: แบ่งช่วงออกเป็นช่วงย่อยและคูณช่วงเข้าด้วยกันในเธรดแยกต่างหากจากนั้นคูณผลลัพธ์กลับเข้าไปในเธรดหลัก

ฉันไม่สามารถหาวิธีการทำงานของ escript ดังนั้นเพียงบันทึกเป็นf.erlและเปิด erl และเรียกใช้:

c(f).
f:m(NUM_TO_CALC, NUM_OF_PROCESSES).

ด้วยการเปลี่ยนตัวที่เหมาะสม

มีประมาณ 8 วินาทีสำหรับ 50000 ใน 2 กระบวนการและ 10 วินาทีสำหรับ 1 กระบวนการบน MacBook Air ของฉัน (ดูอัลคอร์)

หมายเหตุ: เพียงสังเกตว่ามันค้างหากคุณพยายามดำเนินการมากกว่าจำนวนที่จะทำให้เป็นจริง

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