คำถามติดแท็ก compiler-optimization

การเพิ่มประสิทธิภาพคอมไพลเลอร์เกี่ยวข้องกับการปรับคอมไพเลอร์เพื่อลดรันไทม์หรือขนาดอ็อบเจ็กต์หรือทั้งสองอย่าง สิ่งนี้สามารถทำได้โดยใช้อาร์กิวเมนต์ของคอมไพเลอร์ (เช่น CFLAGS, LDFLAGS), ปลั๊กอินคอมไพเลอร์ (เช่น DEHYDRA) หรือการแก้ไขโดยตรงกับคอมไพลเลอร์ (เช่นการแก้ไขซอร์สโค้ด)

10
ทำไมการเติมแบบวนรอบในแบบวนรอบจึงเร็วกว่าการวนซ้ำแบบรวมกันมาก?
สมมติว่าa1, b1, c1และd1ชี้ไปที่หน่วยความจำและกองรหัสตัวเลขของฉันมีห่วงหลักดังต่อไปนี้ const int n = 100000; for (int j = 0; j < n; j++) { a1[j] += b1[j]; c1[j] += d1[j]; } การวนซ้ำนี้จะดำเนินการ 10,000 ครั้งผ่านการforวนรอบนอกอื่น เพื่อเพิ่มความเร็วฉันเปลี่ยนรหัสเป็น: for (int j = 0; j < n; j++) { a1[j] += b1[j]; } for (int j = 0; j < …

12
ทำไม GCC จึงไม่ปรับ a * a * a * a * a ถึง (a * a * a) * (a * a * a)?
ฉันกำลังทำการเพิ่มประสิทธิภาพเชิงตัวเลขในแอปพลิเคชันทางวิทยาศาสตร์ สิ่งหนึ่งที่ฉันสังเกตเห็นคือ GCC จะเพิ่มประสิทธิภาพการโทรpow(a,2)โดยรวบรวมมันเข้าไปa*aแต่การโทรpow(a,6)นั้นไม่ได้รับการปรับปรุงและจะเรียกฟังก์ชั่นห้องสมุดpowซึ่งทำให้ประสิทธิภาพช้าลงอย่างมาก (ตรงกันข้ามIntel C ++ Compiler ที่สามารถเรียกทำงานiccได้จะกำจัดการเรียกใช้ไลบรารีpow(a,6)) สิ่งที่ฉันอยากรู้คือเมื่อฉันแทนที่pow(a,6)ด้วยการa*a*a*a*a*aใช้ GCC 4.5.1 และตัวเลือก " -O3 -lm -funroll-loops -msse4" จะใช้ 5 mulsdคำสั่ง: movapd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 ในขณะที่ถ้าฉันเขียน(a*a*a)*(a*a*a)มันจะผลิต movapd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd …

10
การแทนที่ตัวนับลูป 32 บิตเป็น 64 บิตจะนำเสนอการเบี่ยงเบนประสิทธิภาพที่บ้าคลั่งด้วย _mm_popcnt_u64 บน Intel CPUs
ฉันกำลังมองหาวิธีที่เร็วที่สุดในการจัดpopcountเก็บข้อมูลขนาดใหญ่ ฉันพบลักษณะพิเศษที่แปลกมาก : การเปลี่ยนตัวแปรลูปจากunsignedเป็นuint64_tทำให้ประสิทธิภาพลดลง 50% บนพีซีของฉัน เกณฑ์มาตรฐาน #include <iostream> #include <chrono> #include <x86intrin.h> int main(int argc, char* argv[]) { using namespace std; if (argc != 2) { cerr << "usage: array_size in MB" << endl; return -1; } uint64_t size = atol(argv[1])<<20; uint64_t* buffer = new uint64_t[size/8]; char* charbuffer = …

9
Swift Beta performance: การเรียงลำดับอาร์เรย์
ฉันใช้อัลกอริทึมใน Swift Beta และสังเกตว่าประสิทธิภาพแย่มาก หลังจากขุดลึกฉันรู้ว่าหนึ่งในคอขวดเป็นสิ่งที่ง่ายเหมือนการเรียงลำดับอาร์เรย์ ส่วนที่เกี่ยวข้องอยู่ที่นี่: let n = 1000000 var x = [Int](repeating: 0, count: n) for i in 0..<n { x[i] = random() } // start clock here let y = sort(x) // stop clock here ใน C ++ การดำเนินการที่คล้ายกันใช้เวลา0.06 วินาทีบนคอมพิวเตอร์ของฉัน ใน Python ใช้เวลา0.6 วินาที (ไม่มีลูกเล่นเพียงแค่ y = …

6
เหตุใด GCC จึงสร้างรหัสเร็วขึ้น 15-20% หากฉันปรับขนาดให้เหมาะสมแทนความเร็ว
ฉันสังเกตเห็นครั้งแรกในปี 2009 ว่า GCC (อย่างน้อยในโครงการของฉันและในเครื่องของฉัน) มีแนวโน้มที่จะสร้างรหัสที่เร็วขึ้นอย่างเห็นได้ชัดถ้าฉันปรับขนาด ( -Os) แทนความเร็ว ( -O2หรือ-O3) และฉันสงสัยตั้งแต่นั้นมา ฉันมีการจัดการเพื่อสร้างรหัส (ค่อนข้างโง่) ที่แสดงพฤติกรรมที่น่าแปลกใจนี้และมีขนาดเล็กพอที่จะโพสต์ที่นี่ const int LOOP_BOUND = 200000000; __attribute__((noinline)) static int add(const int& x, const int& y) { return x + y; } __attribute__((noinline)) static int work(int xval, int yval) { int sum(0); for (int i=0; i<LOOP_BOUND; ++i) …

1
ทำไมคอมไพเลอร์ Rust ไม่ปรับโค้ดให้เหมาะสมโดยสมมติว่าการอ้างอิงที่ไม่แน่นอนทั้งสองไม่สามารถใช้นามแฝงได้
เท่าที่ฉันรู้การอ้างอิงนามแฝงตัวชี้ / สามารถขัดขวางความสามารถของคอมไพเลอร์ในการสร้างรหัสที่ดีที่สุดเพราะพวกเขาจะต้องตรวจสอบให้แน่ใจว่าการสร้างไบนารีทำงานอย่างถูกต้องในกรณีที่ทั้งสองอ้างอิง / พอยน์เตอร์นามแฝงแน่นอน ตัวอย่างเช่นในรหัส C ต่อไปนี้ void adds(int *a, int *b) { *a += *b; *a += *b; } เมื่อคอมไพล์clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)ด้วย-O3แฟล็ก 0000000000000000 <adds>: 0: 8b 07 mov (%rdi),%eax 2: 03 06 add (%rsi),%eax 4: 89 07 mov %eax,(%rdi) # The first time 6: 03 06 add …

12
วิธีการรวบรวม Tensorflow ด้วยคำแนะนำ SSE4.2 และ AVX
นี่คือข้อความที่ได้รับจากการรันสคริปต์เพื่อตรวจสอบว่า Tensorflow ทำงานหรือไม่: I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcublas.so.8.0 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcudnn.so.5 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcufft.so.8.0 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcuda.so.1 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcurand.so.8.0 locally W tensorflow/core/platform/cpu_feature_guard.cc:95] The TensorFlow library wasn't compiled …

2
การดำเนินงาน &&& ในค
#include <stdio.h> volatile int i; int main() { int c; for (i = 0; i < 3; i++) { c = i &&& i; printf("%d\n", c); } return 0; } ผลลัพธ์ของโปรแกรมข้างต้นที่คอมไพล์ใช้gccคือ 0 1 1 ด้วย-Wallหรือ-Waddressตัวเลือกgccออกคำเตือน: warning: the address of ‘i’ will always evaluate as ‘true’ [-Waddress] การcประเมินในโปรแกรมข้างต้นเป็นอย่างไร

3
เหตุใด GCC จึงสร้างแอสเซมบลีที่ต่างกันอย่างสิ้นเชิงสำหรับรหัส C เกือบเหมือนกัน
ในขณะที่เขียนเพิ่มประสิทธิภาพftolการทำงานของผมพบว่าพฤติกรรมแปลก ๆ GCC 4.6.1บางอย่างใน ให้ฉันแสดงรหัสก่อน (เพื่อความชัดเจนฉันได้ทำเครื่องหมายความแตกต่าง): fast_trunc_one, C: int fast_trunc_one(int i) { int mantissa, exponent, sign, r; mantissa = (i & 0x07fffff) | 0x800000; exponent = 150 - ((i >> 23) & 0xff); sign = i & 0x80000000; if (exponent < 0) { r = mantissa << -exponent; /* diff …

4
ฉันสามารถใบ้ตัวเพิ่มประสิทธิภาพโดยให้ช่วงของจำนวนเต็มได้หรือไม่
ฉันใช้intประเภทเพื่อเก็บค่า โดยความหมายของโปรแกรมค่าแตกต่างกันเสมอในช่วงที่เล็กมาก (0 - 36) และint(ไม่ใช่ a char) ถูกใช้เพียงเพราะประสิทธิภาพของ CPU ดูเหมือนว่าการเพิ่มประสิทธิภาพทางคณิตศาสตร์พิเศษหลายอย่างสามารถทำได้กับจำนวนเต็มเล็กน้อย การเรียกใช้ฟังก์ชันจำนวนมากในจำนวนเต็มเหล่านั้นอาจถูกปรับให้เหมาะกับการดำเนินการ "เสก" จำนวนน้อยและบางฟังก์ชั่นอาจปรับให้เหมาะกับการค้นหาบนโต๊ะ ดังนั้นเป็นไปได้หรือไม่ที่จะบอกคอมไพเลอร์ว่านี่intเป็นช่วงเล็ก ๆ เสมอและเป็นไปได้หรือไม่ที่คอมไพเลอร์จะทำการปรับแต่งเหล่านั้นให้ดีที่สุด?

2
ทำไมคอมไพเลอร์สามารถปรับแต่งแลมบ์ดาได้ดีกว่าฟังก์ชั่นธรรมดา?
ในหนังสือของเขาThe C++ Standard Library (Second Edition)Nicolai Josuttis ระบุว่า lambdas สามารถปรับให้เหมาะสมโดยคอมไพเลอร์มากกว่าฟังก์ชั่นธรรมดา นอกจากนี้คอมไพเลอร์ C ++ เพิ่มประสิทธิภาพ lambdas ได้ดีกว่าฟังก์ชั่นทั่วไป (หน้า 213) ทำไมถึงเป็นอย่างนั้น? ฉันคิดว่าเมื่อพูดถึงการอินไลน์ก็ไม่น่าจะมีความแตกต่างอีกต่อไป เหตุผลเดียวที่ฉันคิดได้ก็คือคอมไพเลอร์อาจมีบริบทท้องถิ่นที่ดีขึ้นกับลูกแกะและสิ่งเหล่านี้สามารถทำให้สมมติฐานมากขึ้นและดำเนินการเพิ่มประสิทธิภาพมากขึ้น

5
วิธีการดูว่าธง --march = พื้นเมืองจะเปิดใช้งาน?
ฉันกำลังรวบรวมแอป C ++ ของฉันโดยใช้ GCC 4.3 แทนที่จะเลือกการตั้งค่าสถานะการปรับแต่งที่ฉันใช้ด้วยตนเอง-march=nativeซึ่งในทางทฤษฎีแล้วควรเพิ่มการตั้งค่าสถานะการปรับให้เหมาะสมทั้งหมดที่ใช้กับฮาร์ดแวร์ที่ฉันกำลังรวบรวม แต่ฉันจะตรวจสอบการตั้งค่าสถานะที่ใช้งานจริงได้อย่างไร

2
ข้อ จำกัด ของประเภท Nat ในรูปแบบไม่มีรูปแบบ
ในรูปแบบไม่มีรูปแบบ Nat แสดงวิธีการเข้ารหัสตัวเลขธรรมชาติที่ระดับประเภท ใช้เป็นตัวอย่างสำหรับรายการขนาดคงที่ คุณสามารถทำการคำนวณในระดับประเภทเช่นผนวกรายการของNองค์ประกอบเข้ากับรายการKองค์ประกอบและกลับรายการที่ทราบเวลารวบรวมเพื่อให้มีN+Kองค์ประกอบ การเป็นตัวแทนนี้มีความสามารถในการแสดงจำนวนมากเช่น1000000หรือ 2 53หรือสิ่งนี้จะทำให้คอมไพเลอร์สกาล่าจะยอมแพ้?

5
เหตุใดเครื่องมือเพิ่มประสิทธิภาพ GCC 6 ที่ปรับปรุงแล้วจึงใช้งาน C ++ ได้จริง
GCC 6 มีคุณลักษณะเครื่องมือเพิ่มประสิทธิภาพใหม่ : จะถือว่าthisไม่เป็นโมฆะและปรับให้เหมาะสมตามนั้น ตอนนี้การแพร่กระจายช่วงค่าถือว่าตัวชี้ของฟังก์ชันสมาชิก C ++ นี้ไม่ใช่ค่าว่าง กำจัดนี้ null ร่วมกันตรวจสอบตัวชี้แต่ยังแบ่งบางส่วนไม่สอดคล้องรหัสฐาน (เช่น Qt-5, โครเมี่ยม, KDevelop) สามารถใช้การแก้ไขชั่วคราว -fno-delete-null-pointer-checks ชั่วคราวได้ รหัสที่ไม่ถูกต้องสามารถระบุได้โดยใช้ -fsanitize = undefined เอกสารการเปลี่ยนแปลงเรียกสิ่งนี้ว่าเป็นอันตรายอย่างชัดเจนเพราะแบ่งรหัสที่ใช้บ่อยเป็นจำนวนมากอย่างน่าประหลาดใจ เหตุใดสมมติฐานใหม่นี้จึงไม่ใช้งานรหัส C ++ ที่ใช้งานได้จริง มีรูปแบบเฉพาะหรือไม่ที่โปรแกรมเมอร์ไม่ประมาทหรือไม่มีข้อมูลจะพึ่งพาพฤติกรรมที่ไม่ได้กำหนดนี้หรือไม่? ฉันไม่สามารถจินตนาการได้ว่ามีใครเขียนif (this == NULL)เพราะมันแปลกประหลาดมาก

7
เหตุใดคอมไพเลอร์จึงไม่สามารถปรับแต่งลูปการเพิ่มที่คาดเดาได้ให้เหมาะสมกับการคูณ
นี่คือคำถามที่มาถึงใจในขณะที่อ่านคำตอบที่ยอดเยี่ยมโดยMysticialคำถาม: ทำไมมันเร็วขึ้นในการประมวลผลอาร์เรย์เรียงกว่าอาร์เรย์ไม่ได้เรียงลำดับ ? บริบทสำหรับประเภทที่เกี่ยวข้อง: const unsigned arraySize = 32768; int data[arraySize]; long long sum = 0; ในคำตอบของเขาเขาอธิบายว่า Intel Compiler (ICC) เพิ่มประสิทธิภาพสิ่งนี้: for (int i = 0; i < 100000; ++i) for (int c = 0; c < arraySize; ++c) if (data[c] >= 128) sum += data[c]; ... เป็นสิ่งที่เทียบเท่ากับสิ่งนี้: for (int …

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