การเปรียบเทียบ (python เทียบกับ c ++ โดยใช้ BLAS) และ (numpy)


107

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

ฉันมีผู้เข้าแข่งขันสามคนและต้องการทดสอบประสิทธิภาพของพวกเขาด้วยการคูณเมทริกซ์ - เมทริกซ์อย่างง่าย ผู้เข้าแข่งขัน ได้แก่

  1. Numpy ใช้เฉพาะฟังก์ชันของdot.
  2. Python เรียกฟังก์ชัน BLAS ผ่านวัตถุที่ใช้ร่วมกัน
  3. C ++ เรียกฟังก์ชัน BLAS ผ่านวัตถุที่ใช้ร่วมกัน

สถานการณ์

ฉันใช้การคูณเมทริกซ์ - เมทริกซ์สำหรับมิติiต่างๆ iทำงานจาก 5 ถึง 500 โดยเพิ่มขึ้น 5 และเมทริกซ์m1และm2ตั้งค่าดังนี้:

m1 = numpy.random.rand(i,i).astype(numpy.float32)
m2 = numpy.random.rand(i,i).astype(numpy.float32)

1. เป็นก้อน

รหัสที่ใช้มีลักษณะดังนี้:

tNumpy = timeit.Timer("numpy.dot(m1, m2)", "import numpy; from __main__ import m1, m2")
rNumpy.append((i, tNumpy.repeat(20, 1)))

2. Python เรียก BLAS ผ่านวัตถุที่ใช้ร่วมกัน

ด้วยฟังก์ชั่น

_blaslib = ctypes.cdll.LoadLibrary("libblas.so")
def Mul(m1, m2, i, r):

    no_trans = c_char("n")
    n = c_int(i)
    one = c_float(1.0)
    zero = c_float(0.0)

    _blaslib.sgemm_(byref(no_trans), byref(no_trans), byref(n), byref(n), byref(n), 
            byref(one), m1.ctypes.data_as(ctypes.c_void_p), byref(n), 
            m2.ctypes.data_as(ctypes.c_void_p), byref(n), byref(zero), 
            r.ctypes.data_as(ctypes.c_void_p), byref(n))

รหัสทดสอบมีลักษณะดังนี้:

r = numpy.zeros((i,i), numpy.float32)
tBlas = timeit.Timer("Mul(m1, m2, i, r)", "import numpy; from __main__ import i, m1, m2, r, Mul")
rBlas.append((i, tBlas.repeat(20, 1)))

3. c ++ เรียก BLAS ผ่านวัตถุที่ใช้ร่วมกัน

ตอนนี้รหัส c ++ ตามธรรมชาติยาวขึ้นเล็กน้อยดังนั้นฉันจึงลดข้อมูลให้เหลือน้อยที่สุด
ฉันโหลดฟังก์ชันด้วย

void* handle = dlopen("libblas.so", RTLD_LAZY);
void* Func = dlsym(handle, "sgemm_");

ฉันวัดเวลาด้วยgettimeofdayสิ่งนี้:

gettimeofday(&start, NULL);
f(&no_trans, &no_trans, &dim, &dim, &dim, &one, A, &dim, B, &dim, &zero, Return, &dim);
gettimeofday(&end, NULL);
dTimes[j] = CalcTime(start, end);

jลูปทำงานอยู่ที่ไหน20 ครั้ง ฉันคำนวณเวลาที่ผ่านไปด้วย

double CalcTime(timeval start, timeval end)
{
double factor = 1000000;
return (((double)end.tv_sec) * factor + ((double)end.tv_usec) - (((double)start.tv_sec) * factor + ((double)start.tv_usec))) / factor;
}

ผล

ผลลัพธ์จะแสดงในพล็อตด้านล่าง:

ใส่คำอธิบายภาพที่นี่

คำถาม

  1. คุณคิดว่าแนวทางของฉันยุติธรรมหรือมีค่าใช้จ่ายที่ไม่จำเป็นบางอย่างที่ฉันสามารถหลีกเลี่ยงได้?
  2. คุณคาดหวังว่าผลลัพธ์จะแสดงความแตกต่างอย่างมากระหว่างวิธี c ++ และ python หรือไม่? ทั้งสองใช้วัตถุที่ใช้ร่วมกันสำหรับการคำนวณ
  3. เนื่องจากฉันค่อนข้างจะใช้ python สำหรับโปรแกรมของฉันฉันจะทำอย่างไรเพื่อเพิ่มประสิทธิภาพเมื่อเรียกใช้งาน BLAS หรือ LAPACK

ดาวน์โหลด

มาตรฐานที่สมบูรณ์สามารถดาวน์โหลดได้ที่นี่ (เจเอฟเซบาสเตียนทำให้ลิงค์นั้นเป็นไปได้ ^^)


ในแนวทาง ctypes ของคุณคุณมีการจัดสรรหน่วยความจำภายในฟังก์ชันที่วัดได้ รหัส c ++ ของคุณเป็นไปตามแนวทางนี้หรือไม่ แต่เมื่อเทียบกับการคูณเมทริกซ์สิ่งนี้ไม่น่าจะสร้างความแตกต่างได้มากนัก ....
Rocksportrocker

@rocksportrocker คุณถูกต้อง การจัดสรรหน่วยความจำสำหรับrเมทริกซ์ไม่เป็นธรรม ฉันกำลังแก้ไข "ปัญหา" ในขณะนี้และโพสต์ผลลัพธ์ใหม่
Woltan

1. ตรวจสอบให้แน่ใจว่าอาร์เรย์มีเค้าโครงหน่วยความจำเหมือนกันnp.ascontiguousarray()(พิจารณาลำดับ C เทียบกับลำดับ Fortran) 2. ตรวจสอบให้แน่ใจว่าใช้เหมือนกันnp.dot() libblas.so
jfs

@JFSebastian อาร์เรย์ทั้งสองm1และm2มีascontiguousarrayแฟล็กเป็นTrue. และ numpy ใช้วัตถุที่ใช้ร่วมกันเดียวกันกับ C สำหรับลำดับของอาร์เรย์: ขณะนี้ฉันไม่สนใจผลลัพธ์ของการคำนวณดังนั้นคำสั่งจึงไม่เกี่ยวข้อง
Woltan

1
@ Woltan: อย่าใช้ filefactory บริการแย่มาก ฉันได้เพิ่มมาตรฐานของคุณเพื่อ GitHub: woltan-มาตรฐาน หากคุณใช้ github ฉันสามารถเพิ่มคุณเป็นผู้ทำงานร่วมกันได้
jfs

คำตอบ:


58

ผมเคยทำงานมาตรฐานของคุณ ไม่มีความแตกต่างระหว่าง C ++ และ numpy บนเครื่องของฉัน:

เกณฑ์มาตรฐานของ Woltan

คุณคิดว่าแนวทางของฉันยุติธรรมหรือมีค่าใช้จ่ายที่ไม่จำเป็นบางอย่างที่ฉันสามารถหลีกเลี่ยงได้?

ดูเหมือนจะยุติธรรมเนื่องจากไม่มีความแตกต่างในผลลัพธ์

คุณคาดหวังว่าผลลัพธ์จะแสดงความแตกต่างอย่างมากระหว่างวิธี c ++ และ python หรือไม่? ทั้งสองใช้วัตถุที่ใช้ร่วมกันสำหรับการคำนวณ

ไม่

เนื่องจากฉันค่อนข้างจะใช้ python สำหรับโปรแกรมของฉันฉันจะทำอย่างไรเพื่อเพิ่มประสิทธิภาพเมื่อเรียกใช้งาน BLAS หรือ LAPACK

ตรวจสอบให้แน่ใจว่า numpy ใช้ไลบรารี BLAS / LAPACK เวอร์ชันที่ปรับให้เหมาะสมที่สุดบนระบบของคุณ


4
แล้วโปสเตอร์ต้นฉบับทำผิดอะไร? ฉันหวังว่าเขาจะแสดงความคิดเห็นในโพสต์นี้ เขายืนยันว่า Numpy เร็วเท่า C ++ หรือไม่?
wmac

รหัส C ++ ของคุณทำงานช้ากว่าโปสเตอร์ดั้งเดิม คุณรวบรวมภายใต้การเพิ่มประสิทธิภาพหรือไม่?
cdcdcd

@cdcdcd มันไม่ใช่รหัสของฉัน คลิกลิงก์และเรียกใช้การเปรียบเทียบด้วยตัวคุณเองด้วยตัวเลือกการเพิ่มประสิทธิภาพต่างๆ (ดู Makefile) แม้ว่าโค้ดจะไม่คอมไพล์ใหม่ทั้ง blas หรือ lapack
jfs

73

อัพเดท (30.07.2014):

ฉันเรียกใช้เกณฑ์มาตรฐานใหม่ใน HPC ใหม่ของเรา ทั้งฮาร์ดแวร์และซอฟต์แวร์สแต็กเปลี่ยนไปจากการตั้งค่าในคำตอบเดิม

ฉันใส่ผลลัพธ์ในGoogle สเปรดชีต (มีผลลัพธ์จากคำตอบเดิมด้วย)

ฮาร์ดแวร์

HPC ของเรามีสองโหนดที่แตกต่างกันหนึ่งโหนดที่มีซีพียู Intel Sandy Bridge และอีกโหนดหนึ่งมีซีพียู Ivy Bridge รุ่นใหม่:

แซนดี้ (MKL, OpenBLAS, ATLAS):

  • CPU : 2 x 16 Intel (R) Xeon (R) E2560 Sandy Bridge @ 2.00GHz (16 คอร์)
  • แรม : 64 GB

ไอวี่ (MKL, OpenBLAS, ATLAS):

  • CPU : 2 x 20 Intel (R) Xeon (R) E2680 V2 Ivy Bridge @ 2.80GHz (20 Cores, with HT = 40 Cores)
  • แรม : 256 GB

ซอฟต์แวร์

สแต็กซอฟต์แวร์มีไว้สำหรับทั้งสองโหนด sam แทนที่จะGotoBLAS2 , OpenBLASถูกนำมาใช้และยังมีแบบมัลติเธรด ATLASหน่ายที่ถูกกำหนดเป็น 8 เธรด (hardcoded)

  • ระบบปฏิบัติการ : Suse
  • Intel Compiler : ictce-5.3.0
  • หมายเลข: 1.8.0
  • OpenBLAS: 0.2.6
  • ATLAS : 3.8.4

Dot-Product Benchmark

Benchmark-code เหมือนกับด้านล่าง อย่างไรก็ตามสำหรับเครื่องใหม่ผมยังวิ่งมาตรฐานสำหรับเมทริกซ์ขนาด5000และ8000
ตารางด้านล่างประกอบด้วยผลการเปรียบเทียบจากคำตอบเดิม (เปลี่ยนชื่อเป็น: MKL -> Nehalem MKL, Netlib Blas -> Nehalem Netlib BLAS เป็นต้น)

การคูณเมทริกซ์ (ขนาด = [1,000,2000,3000,5000,8000])

ประสิทธิภาพเธรดเดียว: ประสิทธิภาพเธรดเดียว

ประสิทธิภาพแบบมัลติเธรด (8 เธรด): ประสิทธิภาพแบบมัลติเธรด (8 เธรด)

เธรดเทียบกับขนาดเมทริกซ์ (Ivy Bridge MKL) : ขนาดเมทริกซ์เทียบกับเธรด

Benchmark Suite

ชุดมาตรฐาน

ประสิทธิภาพเธรดเดียว: ใส่คำอธิบายภาพที่นี่

มัลติเธรด (8 เธรด) ประสิทธิภาพ: ใส่คำอธิบายภาพที่นี่

สรุป

ผลการเปรียบเทียบใหม่จะคล้ายกับผลลัพธ์ในคำตอบเดิม OpenBLASและMKLดำเนินการในระดับเดียวกันยกเว้นการทดสอบEigenvalue eigenvalueดำเนินการทดสอบเพียงได้ดีพอสมควรในOpenBLASในโหมดเกลียวเดียว ในโหมดมัลติเธรดประสิทธิภาพจะแย่ลง

"ขนาดเมทริกซ์ VS หัวข้อกราฟ"ยังแสดงให้เห็นว่าถึงแม้จะ MKL เช่นเดียวกับ OpenBLAS ทั่วไประดับดีมีจำนวนแกน / กระทู้, มันขึ้นอยู่กับขนาดของเมทริกซ์ สำหรับเมทริกซ์ขนาดเล็กการเพิ่มคอร์มากขึ้นจะไม่ช่วยเพิ่มประสิทธิภาพมากนัก

นอกจากนี้ยังมีประสิทธิภาพเพิ่มขึ้นประมาณ 30% จากSandy Bridgeเป็นIvy Bridgeซึ่งอาจเป็นเพราะอัตราสัญญาณนาฬิกาที่สูงขึ้น (+ 0.8 Ghz) และ / หรือสถาปัตยกรรมที่ดีกว่า


คำตอบเดิม (04.10.2011):

เมื่อไม่นานมานี้ฉันต้องเพิ่มประสิทธิภาพการคำนวณพีชคณิตเชิงเส้น / อัลกอริทึมที่เขียนด้วย python โดยใช้ numpy และ BLAS ดังนั้นฉันจึงเปรียบเทียบ / ทดสอบการกำหนดค่า numpy / BLAS ที่แตกต่างกัน

ฉันทดสอบโดยเฉพาะ:

  • Numpy กับ ATLAS
  • Numpy กับGotoBlas2 (1.13)
  • Numpy กับ MKL (11.1 / 073)
  • Numpy พร้อม Accelerate Framework (Mac OS X)

ฉันใช้เกณฑ์มาตรฐานที่แตกต่างกันสองแบบ:

  1. ผลิตภัณฑ์ดอทอย่างง่ายของเมทริกซ์ที่มีขนาดแตกต่างกัน
  2. ชุดมาตรฐานซึ่งสามารถพบได้ที่นี่

นี่คือผลลัพธ์ของฉัน:

เครื่องจักร

ลินุกซ์ (MKL, ATLAS, No-MKL, GotoBlas2):

  • ระบบปฏิบัติการ : Ubuntu Lucid 10.4 64 Bit.
  • CPU : 2 x 4 Intel (R) Xeon (R) E5504 @ 2.00GHz (8 คอร์)
  • แรม : 24 GB
  • Intel Compiler : 11.1 / 073
  • Scipy : 0.8
  • Numpy : 1.5

Mac Book Pro (Accelerate Framework):

  • ระบบปฏิบัติการ : MacOS X Snow Leopard (10.6)
  • CPU : 1 Intel Core 2 Duo 2.93 Ghz (2 คอร์)
  • แรม : 4 GB
  • ไซปี้ : 0.7
  • ตัวเลข : 1.3

เซิร์ฟเวอร์ Mac (Accelerate Framework):

  • ระบบปฏิบัติการ : MacOS X Snow Leopard Server (10.6)
  • CPU : 4 X Intel (R) Xeon (R) E5520 @ 2.26 Ghz (8 คอร์)
  • แรม : 4 GB
  • Scipy : 0.8
  • ตัวเลข : 1.5.1

มาตรฐานผลิตภัณฑ์ Dot

รหัส :

import numpy as np
a = np.random.random_sample((size,size))
b = np.random.random_sample((size,size))
%timeit np.dot(a,b)

ผลลัพธ์ :

    ระบบ | ขนาด = 1000 | ขนาด = 2000 | ขนาด = 3000 |
netlib BLAS | 1350 มิลลิวินาที | 10900 มิลลิวินาที | 39200 มิลลิวินาที |    
ATLAS (1 CPU) | 314 มิลลิวินาที | 2560 มิลลิวินาที | 8700 มิลลิวินาที |     
MKL (1 ซีพียู) | 268 มิลลิวินาที | 2110 มิลลิวินาที | 7120 มิลลิวินาที |
MKL (2 ซีพียู) | - | - | 3660 มิลลิวินาที |
MKL (8 ซีพียู) | 39 มิลลิวินาที | 319 มิลลิวินาที | 1,000 มิลลิวินาที |
GotoBlas2 (1 CPU) | 266 มิลลิวินาที | 2100 มิลลิวินาที | 7280 มิลลิวินาที |
GotoBlas2 (2 ซีพียู) | 139 มิลลิวินาที | 1009 มิลลิวินาที | 3690 มิลลิวินาที |
GotoBlas2 (8 ซีพียู) | 54 มิลลิวินาที | 389 มิลลิวินาที | 1250 มิลลิวินาที |
Mac OS X (1 CPU) | 143 มิลลิวินาที | 1060 มิลลิวินาที | 3605 มิลลิวินาที |
Mac Server (1 CPU) | 92 มิลลิวินาที | 714 มิลลิวินาที | 2130 มิลลิวินาที |

Dot Product Benchmark - แผนภูมิ

Benchmark Suite

รหัส :
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับชุดมาตรฐานดูที่นี่

ผลลัพธ์ :

    ระบบ | ค่าลักษณะเฉพาะ | svd | det | inv | จุด |
netlib BLAS | 1688 มิลลิวินาที | 13102 มิลลิวินาที | 438 มิลลิวินาที | 2155 มิลลิวินาที | 3522 มิลลิวินาที |
ATLAS (1 CPU) | 1210 มิลลิวินาที | 5897 มิลลิวินาที | 170 มิลลิวินาที | 560 มิลลิวินาที | 893 มิลลิวินาที |
MKL (1 ซีพียู) | 691 มิลลิวินาที | 4475 มิลลิวินาที | 141 มิลลิวินาที | 450 มิลลิวินาที | 736 มิลลิวินาที |
MKL (2 ซีพียู) | 552 มิลลิวินาที | 2718 มิลลิวินาที | 96 มิลลิวินาที | 267 มิลลิวินาที | 423 มิลลิวินาที |
MKL (8 ซีพียู) | 525 มิลลิวินาที | 1679 มิลลิวินาที | 60 มิลลิวินาที | 137 มิลลิวินาที | 197 มิลลิวินาที |  
GotoBlas2 (1 CPU) | 2124 มิลลิวินาที | 4636 มิลลิวินาที | 147 มิลลิวินาที | 456 มิลลิวินาที | 743 มิลลิวินาที |
GotoBlas2 (2 ซีพียู) | 1560 มิลลิวินาที | 3278 มิลลิวินาที | 116 มิลลิวินาที | 295 มิลลิวินาที | 460 มิลลิวินาที |
GotoBlas2 (8 ซีพียู) | 741 มิลลิวินาที | 2914 มิลลิวินาที | 82 มิลลิวินาที | 262 มิลลิวินาที | 192 มิลลิวินาที |
Mac OS X (1 CPU) | 948 มิลลิวินาที | 4339 มิลลิวินาที | 151 มิลลิวินาที | 318 มิลลิวินาที | 566 มิลลิวินาที |
Mac Server (1 CPU) | 1033 มิลลิวินาที | 3645 มิลลิวินาที | 99 มิลลิวินาที | 232 มิลลิวินาที | 342 มิลลิวินาที |

Benchmark Suite - แผนภูมิ

การติดตั้ง

การติดตั้งMKLรวมถึงการติดตั้ง Intel Compiler Suite ที่สมบูรณ์ซึ่งค่อนข้างตรงไปตรงมา อย่างไรก็ตามเนื่องจากข้อบกพร่อง / ปัญหาบางอย่างในการกำหนดค่าและการรวบรวม numpy ด้วยการสนับสนุน MKL นั้นค่อนข้างยุ่งยาก

GotoBlas2เป็นแพ็คเกจขนาดเล็กที่สามารถรวบรวมเป็นไลบรารีที่ใช้ร่วมกันได้อย่างง่ายดาย อย่างไรก็ตามเนื่องจากข้อผิดพลาดคุณต้องสร้างไลบรารีที่ใช้ร่วมกันอีกครั้งหลังจากสร้างไลบรารีเพื่อใช้กับ numpy
นอกเหนือจากการสร้างนี้แล้วสำหรับแพลตฟอร์มเป้าหมายหลายรายการไม่ได้ผลด้วยเหตุผลบางประการ ดังนั้นฉันต้องสร้างไฟล์. soสำหรับแต่ละแพลตฟอร์มที่ฉันต้องการมีไฟล์ libgoto2.so ที่ปรับให้เหมาะสม

หากคุณติดตั้ง numpy จากที่เก็บของ Ubuntu ระบบจะติดตั้งและกำหนดค่า numpy เพื่อใช้ATLASโดยอัตโนมัติ การติดตั้งATLASจากแหล่งที่มาอาจใช้เวลาสักครู่และต้องใช้ขั้นตอนเพิ่มเติม (Fortran ฯลฯ )

หากคุณติดตั้ง numpy บนเครื่อง Mac OS X กับตำรวจหรือMac พอร์ตมันอาจจะ numpy กำหนดค่าใช้ATLASหรือแอปเปิ้ลเร่งกรอบ คุณสามารถตรวจสอบได้โดยการทำงาน ldd บน numpy.core._dotblasไฟล์หรือโทรnumpy.show_config ()

ข้อสรุป

MKLดำเนินการตามที่ดีที่สุดอย่างใกล้ชิดโดยGotoBlas2
ในการทดสอบค่าลักษณะเฉพาะ GotoBlas2 มีประสิทธิภาพแย่กว่าที่คาดไว้อย่างน่าประหลาดใจ ไม่แน่ใจว่าทำไมถึงเป็นเช่นนี้
Accelerate Framework ของ Appleทำงานได้ดีมากโดยเฉพาะในโหมดเธรดเดียว (เมื่อเทียบกับการใช้งาน BLAS อื่น ๆ )

ทั้งGotoBlas2และMKLปรับขนาดได้ดีมากด้วยจำนวนเธรด ดังนั้นหากคุณต้องจัดการกับเมทริกซ์ขนาดใหญ่ที่รันบนหลายเธรดจะช่วยได้มาก

ไม่ว่าในกรณีใดอย่าใช้การใช้งานnetlib blasเริ่มต้นเนื่องจากเป็นวิธีที่ช้าเกินไปสำหรับงานด้านการคำนวณที่ร้ายแรง

ในคลัสเตอร์ของเราผมยังติดตั้งเอเอ็มดี ACMLและประสิทธิภาพการทำงานคล้ายกับMKLและGotoBlas2 ฉันไม่มีตัวเลขที่ยาก

ฉันอยากแนะนำให้ใช้GotoBlas2 เป็นการส่วนตัวเพราะติดตั้งง่ายกว่าและฟรี

หากคุณต้องการโค้ดใน C ++ / C ให้ตรวจสอบEigen3ซึ่งควรจะมีประสิทธิภาพดีกว่าMKL / GotoBlas2ในบางกรณีและยังใช้งานง่ายอีกด้วย


ขอบคุณมากสำหรับคำตอบอย่างละเอียดนี้!
Woltan

ครอบคลุมมากขอบคุณ! ฉันสงสัยว่าสามปีต่อมา OpenBLAS (เท่าที่ฉันรู้มันเป็นลูกหลานของ GotoBLAS) จะทำงานได้ดีกว่าหรือไม่ ฉันได้อ่านบางแห่งที่มีประสิทธิภาพดีกว่า MKL แต่ไม่สามารถหาแหล่งที่มาได้ในขณะนี้

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

@ วิลเลียม: โดยปกติคุณไม่จำเป็นต้องเชื่อมโยง scipy กับ openblas โดยเฉพาะเนื่องจากจะใช้การกำหนดค่า numpy ระหว่างการติดตั้งและจริงๆแล้วการโทร BLAS / Lapack ส่วนใหญ่จะถูกส่งต่อไปยังจำนวน ดังนั้นหากมีการเชื่อมโยง numpy กับ openblas อย่างถูกต้องทุกอย่างจะทำงานได้ดี
Üส่ง

@ Ümit: ขอบคุณ! ฉันพยายามตั้งค่า numpy เพื่อเชื่อมโยงกับ MKL ในขณะนี้

20

นี่คือเกณฑ์มาตรฐานอื่น (บน Linux เพียงพิมพ์make): http://dl.dropbox.com/u/5453551/blas_call_benchmark.zip

http://dl.dropbox.com/u/5453551/blas_call_benchmark.png

ฉันไม่เห็นความแตกต่างใด ๆ ระหว่างวิธีการต่างๆสำหรับเมทริกซ์ขนาดใหญ่ระหว่าง Numpy, Ctypes และ Fortran (Fortran แทนที่จะเป็น C ++ - และหากมีความสำคัญเกณฑ์มาตรฐานของคุณอาจเสีย)

CalcTimeฟังก์ชัน ของคุณใน C ++ ดูเหมือนจะมีข้อผิดพลาดในการลงชื่อ ควรจะแทน... + ((double)start.tv_usec)) ... - ((double)start.tv_usec))บางทีเกณฑ์มาตรฐานของคุณอาจมีจุดบกพร่องอื่น ๆ เช่นการเปรียบเทียบระหว่างไลบรารี BLAS ที่แตกต่างกันหรือการตั้งค่า BLAS ที่แตกต่างกันเช่นจำนวนเธรดหรือระหว่างเวลาจริงกับเวลา CPU

แก้ไข : ไม่สามารถนับวงเล็บปีกกาในCalcTimeฟังก์ชันได้ - ไม่เป็นไร

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


หากต้องการทราบว่า BLAS Numpy ใดเชื่อมโยงกับให้ทำ:

$ python
Python 2.7.2+ (ค่าเริ่มต้น 16 ส.ค. 2011, 07:24:41 น.) 
[GCC 4.6.1] บน linux2.0
พิมพ์ "help", "copyright", "credit" หรือ "license" เพื่อดูข้อมูลเพิ่มเติม
>>> นำเข้า numpy.core._dotblas
>>> numpy.core._dotblas .__ file__
'/usr/lib/pymodules/python2.7/numpy/core/_dotblas.so'
>>> 
$ ldd /usr/lib/pymodules/python2.7/numpy/core/_dotblas.so
    linux-vdso.so.1 => (0x00007fff5ebff000)
    libblas.so.3gf => /usr/lib/libblas.so.3gf (0x00007fbe618b3000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbe61514000)

อัปเดต : หากคุณไม่สามารถนำเข้า numpy.core._dotblas ได้แสดงว่า Numpy ของคุณกำลังใช้ BLAS สำเนาสำรองภายในซึ่งช้ากว่าและไม่ได้ตั้งใจที่จะใช้ในการประมวลผลประสิทธิภาพ! คำตอบจาก @Woltan ด้านล่างระบุว่านี่คือคำอธิบายความแตกต่างที่เขา / เธอเห็นใน Numpy เทียบกับ Ctypes + BLAS

ในการแก้ไขสถานการณ์คุณต้องใช้ ATLAS หรือ MKL --- ตรวจสอบคำแนะนำเหล่านี้: http://scipy.org/Installing_SciPy/Linux การกระจาย Linux ส่วนใหญ่มาพร้อมกับ ATLAS ดังนั้นตัวเลือกที่ดีที่สุดคือการติดตั้งlibatlas-devแพ็คเกจ (ชื่ออาจแตกต่างกันไป) .


ฉันใช้เกณฑ์มาตรฐานของคุณ ผลลัพธ์ เหมือนกัน
jfs

ขอบคุณมากสำหรับการโพสต์ของคุณ ฉันวิ่งมาตรฐานของคุณด้วยนี้ผล ดังนั้นฉันไม่สามารถสร้างซ้ำของคุณได้ ในการตรวจสอบ Blas numpy ของฉันใช้: import numpy.core._dotblasฉันไม่สามารถ อะไรคือปัญหาที่นี่? ฉันจะพยายามทำความสะอาดเกณฑ์มาตรฐานของฉันเขียน makefile เพื่อให้คนอื่นทดสอบ
Woltan

2
@ Woltan: ความจริงที่ว่าคุณไม่สามารถนำเข้า numpy.core._dotblas ได้หมายความว่า Numpy ของคุณกำลังใช้ BLAS สำเนาสำรองภายใน ( ช้ากว่าและไม่ได้ตั้งใจจะใช้ในการประมวลผลประสิทธิภาพ!) แทนที่จะเป็นไลบรารี BLAS ที่คุณมี ในระบบของคุณ สิ่งนี้อธิบายถึงผลลัพธ์ที่คุณได้รับจากเกณฑ์มาตรฐาน ในการแก้ไขสถานการณ์คุณต้องติดตั้ง BLAS เวอร์ชัน Numpy ที่สามารถทำงานร่วมกับ --- ซึ่งหมายถึง ATLAS หรือ MKL นี่คือชุดคำแนะนำ: scipy.org/Installing_SciPy/Linux
pv.

@pv: คุณสามารถเรียกใช้เกณฑ์มาตรฐานของ Woltanเพื่อเปรียบเทียบผลลัพธ์ได้หรือไม่
jfs

1
บน Mac คุณสามารถใช้otool -Lแทนlddบน Linux ได้
RichVel

9

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

ฉันคิดว่าวิธีการ numpy / python จะไม่เพิ่มค่าใช้จ่ายมากนักสำหรับเมทริกซ์ของความซับซ้อนที่สมเหตุสมผลเนื่องจากเมื่อความซับซ้อนเพิ่มขึ้นสัดส่วนที่ python เข้าร่วมควรมีขนาดเล็ก ฉันสนใจผลลัพธ์ทางด้านขวามือของกราฟมากกว่า แต่คำสั่งของความคลาดเคลื่อนของขนาดที่แสดงจะเป็นการรบกวน

ฉันสงสัยว่าคุณกำลังใช้อัลกอริทึมที่ดีที่สุดที่ numpy สามารถใช้ประโยชน์ได้ จากคู่มือการรวบรวมสำหรับ linux:

"Build FFTW (3.1.2): เวอร์ชัน SciPy> = 0.7 และ Numpy> = 1.2: เนื่องจากปัญหาด้านใบอนุญาตการกำหนดค่าและการบำรุงรักษาที่รองรับ FFTW จึงถูกลบออกในเวอร์ชันของ SciPy> = 0.7 และ NumPy> = 1.2 แทนในขณะนี้ใช้ fftpack เวอร์ชันในตัวมีสองวิธีในการใช้ประโยชน์จากความเร็วของ FFTW หากจำเป็นสำหรับการวิเคราะห์ของคุณดาวน์เกรดเป็นเวอร์ชัน Numpy / Scipy ที่มีการรองรับติดตั้งหรือสร้าง Wrapper FFTW ของคุณเองดูhttp: //developer.berlios.de/projects/pyfftw/เป็นตัวอย่างที่ไม่ได้รับการรับรอง "

คุณรวบรวม numpy ด้วย mkl หรือไม่? ( http://software.intel.com/en-us/articles/intel-mkl/ ) หากคุณใช้งาน linux คำแนะนำในการคอมไพล์ numpy ด้วย mkl อยู่ที่นี่: http://www.scipy.org/Installing_SciPy/Linux#head-7ce43956a69ec51c6f2cedd894a4715d5bfff974 (แม้จะมี url) ส่วนสำคัญคือ:

[mkl]
library_dirs = /opt/intel/composer_xe_2011_sp1.6.233/mkl/lib/intel64
include_dirs = /opt/intel/composer_xe_2011_sp1.6.233/mkl/include
mkl_libs = mkl_intel_lp64,mkl_intel_thread,mkl_core 

หากคุณใช้ windows คุณสามารถรับไบนารีที่คอมไพล์ด้วย mkl (และรับ pyfftw และอัลกอริทึมที่เกี่ยวข้องอื่น ๆ อีกมากมาย) ได้ที่: http://www.lfd.uci.edu/~gohlke/pythonlibs/ด้วย a หนี้เพื่อแสดงความขอบคุณ Christoph Gohlke ที่ห้องปฏิบัติการ Fluorescence Dynamics, UC Irvine

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


ขอบคุณสำหรับ "ความคิดเห็น" อย่างละเอียดนะครับ ^^. เพื่อชี้แจงการติดตั้ง / numpy / หน่ายหลามฉัน: ผมทำตามนี้คู่มือการติดตั้ง ฉันใช้ระบบปฏิบัติการ linux และเวอร์ชัน ได้แก่ Python 2.7, Scipy 0.9 Numpy 1.6 น่าเสียดายที่ฉันไม่ได้สร้าง FFTW มาก่อนมือฉันก็ไม่ได้ใช้ mkl ...
Woltan

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

คุณสามารถลองสร้าง ATLAS ได้เช่นกัน แต่ฟังดูเหมือนปวดหัวมากเกินไปสำหรับความต้องการด้านประสิทธิภาพของฉันดังนั้นฉันจึงไม่มีประสบการณ์ใด ๆ ฉันจินตนาการว่าคุณสนใจที่จะใช้ python แต่สามารถใช้ C ++ ได้มีบางจุดที่ค่าติดตั้งในการรวบรวมข้อมูลพิเศษจำนวนมากจะมากกว่าการประหยัดภาษาและการทำ c ++ จะง่ายกว่า แต่ mkl และ fftw ควรตรงไปตรงมา
ดูหมิ่น

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