मैं समझने की कोशिश करता हूं कि सी ++ कंपाइलर लूप संलयन करने में सक्षम नहीं है और कब नहीं।सी ++ में लूप संलयन (कंपाइलर की मदद कैसे करें?)
निम्नलिखित कोड वेक्टर में सभी मानों के वर्ग डबल्स (f(x) = (2*x)^2
) की गणना करने के दो अलग-अलग तरीकों के प्रदर्शन को मापता है।
#include <chrono>
#include <iostream>
#include <numeric>
#include <vector>
constexpr int square(int x)
{
return x * x;
}
constexpr int times_two(int x)
{
return 2 * x;
}
// map ((^2) . (^2)) $ [1,2,3]
int manual_fusion(const std::vector<int>& xs)
{
std::vector<int> zs;
zs.reserve(xs.size());
for (int x : xs)
{
zs.push_back(square(times_two(x)));
}
return zs[0];
}
// map (^2) . map (^2) $ [1,2,3]
int two_loops(const std::vector<int>& xs)
{
std::vector<int> ys;
ys.reserve(xs.size());
for (int x : xs)
{
ys.push_back(times_two(x));
}
std::vector<int> zs;
zs.reserve(ys.size());
for (int y : ys)
{
zs.push_back(square(y));
}
return zs[0];
}
template <typename F>
void test(F f)
{
const std::vector<int> xs(100000000, 42);
const auto start_time = std::chrono::high_resolution_clock::now();
const auto result = f(xs);
const auto end_time = std::chrono::high_resolution_clock::now();
const auto elapsed = end_time - start_time;
const auto elapsed_us = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
std::cout << elapsed_us/1000 << " ms - " << result << std::endl;
}
int main()
{
test(manual_fusion);
test(two_loops);
}
दो छोरों takes about twice as much time एक पाश के साथ संस्करण के रूप में, जीसीसी और बजना के लिए -O3
भी साथ साथ संस्करण।
क्या कंप्रेसर को two_loops
को दूसरे लूप में इन-प्लेस के बिना manual_fusion
के रूप में तेज़ी से अनुकूलित करने की अनुमति देने का कोई तरीका है? कारण मैं पूछ रहा हूं कि मैं अपनी लाइब्रेरी FunctionalPlus पर fplus::enumerate(fplus::transform(f, xs));
की तरह जंजीर कॉल करना चाहता हूं।
को push_back है आप दूसरे संस्करण में दो आवंटन किया है। चलो इसे चालू करें (संशोधित करें) 'ys' सीधे –
आपको बहुत धन्यवाद, [यह काम करता है] (http://ideone.com/I17kdT)! क्या आपको लगता है कि संकलक आवंटन को अनुकूलित करने की संभावना है? –
मुझे ऐसा नहीं लगता है। ऐसा करने के लिए बहुत अधिक अनुमान लगाया जाएगा (एक अनुमान पहले से ही अनुकूलन को मना करता है) –