অর্ডার করা সংখ্যার দক্ষ স্থিতিশীল যোগফল


12

আমার কাছে ভাসমান পয়েন্ট পজিটিভ সংখ্যাগুলির একটি দীর্ঘ দীর্ঘ তালিকা ( std::vector<float>আকার ~ 1000)। সংখ্যা হ্রাস ক্রম অনুসারে বাছাই করা হয়। যদি আমি তাদের অর্ডার অনুসরণ করে যোগ করি:

for (auto v : vec) { sum += v; }

আমার ধারণা, আমার কিছু সংখ্যক স্থায়িত্বের সমস্যা হতে পারে, যেহেতু ভেক্টরের শেষের sumচেয়ে অনেক বড় হবে v। সবচেয়ে সহজ সমাধানটি হ'ল বিপরীত ক্রমে ভেক্টরকে অতিক্রম করা। আমার প্রশ্ন: এটি কি দক্ষ পাশাপাশি ফরোয়ার্ড কেস? আমি আরও ক্যাশে অনুপস্থিত হবে?

অন্য কোন স্মার্ট সমাধান আছে কি?


1
গতির প্রশ্নের উত্তর দেওয়া সহজ। এটি বেঞ্চমার্ক।
ডেভিড স্পাতার্টো

গতি কি নির্ভুলতার চেয়ে গুরুত্বপূর্ণ?
স্টার্ক

বেশ সদৃশ নয়, তবে খুব অনুরূপ প্রশ্ন: ফ্লোট ব্যবহার করে সিরিজের সমষ্টি
acraig5075

4
আপনাকে নেতিবাচক সংখ্যাগুলিতে মনোযোগ দিতে হতে পারে।
এপ্রোগ্রামার

3
যদি আপনি প্রকৃতপক্ষে উচ্চ ডিগ্রি পর্যন্ত নির্ভুলতার বিষয়ে চিন্তা করেন তবে কাহান সমষ্টিটি দেখুন
ম্যাক্স ল্যাঙ্গোফ

উত্তর:


3

আমার ধারণা আমার কিছু সংখ্যক স্থায়িত্বের সমস্যা থাকতে পারে

সুতরাং এটি জন্য পরীক্ষা। বর্তমানে আপনার একটি অনুমানমূলক সমস্যা রয়েছে, যার অর্থ এটি কোনও সমস্যা নয়।

যদি আপনি পরীক্ষা করেন, এবং অনুমানকৃত কোনও বাস্তব সমস্যার মধ্যে রূপ দেয় তবে আপনার এটি ঠিক করার বিষয়ে আপনার চিন্তিত হওয়া উচিত।

এটি হ'ল - ভাসমান-পয়েন্ট যথার্থতা সমস্যার কারণ হতে পারে, তবে অন্য যে কোনও বিষয়টিকে অগ্রাধিকার দেওয়ার আগে আপনি এটি নিশ্চিত করতে পারবেন যে এটি আপনার ডেটার জন্য সত্যই কাজ করে কিনা।

... আমি আরও ক্যাশে মিস করব?

এক হাজার ভাসমান 4Kb - এটি একটি আধুনিক গণ-বাজার ব্যবস্থায় ক্যাশে মাপসই করা হবে (যদি আপনার মনে অন্য কোনও প্ল্যাটফর্ম থাকে তবে এটি কী তা আমাদের বলুন)।

একমাত্র ঝুঁকি হ'ল পিছনের দিকে পুনরাবৃত্তি করার সময় উপস্থাপক আপনাকে সাহায্য করবে না, তবে অবশ্যই আপনার ভেক্টর ইতিমধ্যে ক্যাশে থাকতে পারে। আপনার সম্পূর্ণ প্রোগ্রামের প্রসঙ্গে আপনি প্রোফাইল না করা পর্যন্ত আপনি সত্যই এটি নির্ধারণ করতে পারবেন না, সুতরাং আপনার একটি সম্পূর্ণ প্রোগ্রাম না হওয়া পর্যন্ত এটি নিয়ে চিন্তার কোনও লাভ নেই।

অন্য কোন স্মার্ট সমাধান আছে কি?

সমস্যাগুলি হয়ে উঠতে পারে এমন সমস্যাগুলি সম্পর্কে চিন্তা করবেন না যতক্ষণ না তারা আসলে সমস্যা হয়ে যায়। সর্বাধিক এটি সম্ভাব্য বিষয়গুলি লক্ষ্য করা এবং আপনার কোডটি কাঠামোবদ্ধ করার পক্ষে মূল্যবান যাতে আপনি সমস্ত কিছু পুনরায় না লিখে, সাবধানতার সাথে অনুকূলিতকরণের পরে সবচেয়ে সহজতম সমাধানটি প্রতিস্থাপন করতে পারেন।


5

আমি আপনার ব্যবহারের কেসটি বেঞ্চ-চিহ্নিত করেছি এবং ফলাফলগুলি (সংযুক্ত চিত্র দেখুন) সেই দিকে নির্দেশ করে যা এটি সামনে বা পিছনে লুপ করতে কোনও পারফরম্যান্সের পার্থক্য করে না।

আপনি আপনার হার্ডওয়্যার + সংকলকটিও পরিমাপ করতে চাইতে পারেন।


যোগফল সম্পাদন করতে এসটিএল ব্যবহার করে এটি ডেটা ম্যানুয়াল লুপিংয়ের মতো দ্রুত তবে অনেক বেশি অভিব্যক্তিপূর্ণ।

বিপরীত জমার জন্য নিম্নলিখিতটি ব্যবহার করুন:

std::accumulate(rbegin(data), rend(data), 0.0f);

এগিয়ে জমে থাকার সময়:

std::accumulate(begin(data), end(data), 0.0f);

এখানে চিত্র বর্ণনা লিখুন


যে ওয়েবসাইট দুর্দান্ত দুর্দান্ত। কেবল নিশ্চিত হওয়া: আপনি এলোমেলো প্রজন্মের সময় দিচ্ছেন না, তাই না?
রাগ্গেরো তুরা

না, stateলুপের কেবলমাত্র অংশ শেষ হয়েছে।
ডেভিড স্পাতার্টো

2

সবচেয়ে সহজ সমাধানটি হ'ল বিপরীত ক্রমে ভেক্টরকে অতিক্রম করা। আমার প্রশ্ন: এটি কি দক্ষ পাশাপাশি ফরোয়ার্ড কেস? আমি আরও ক্যাশে অনুপস্থিত হবে?

হ্যাঁ এটি দক্ষ। আপনার হার্ডওয়্যার থেকে শাখা পূর্বাভাস এবং স্মার্ট ক্যাশে কৌশলটি অনুক্রমিক অ্যাক্সেসের জন্য সুরযুক্ত। আপনি নিরাপদে আপনার ভেক্টর জমা করতে পারেন:

#include <numeric>

auto const sum = std::accumulate(crbegin(v), crend(v), 0.f);

2
আপনি কি পরিষ্কার করতে পারেন: এই প্রসঙ্গে "অনুক্রমিক অ্যাক্সেস" এর অর্থ এগিয়ে, পিছিয়ে, বা উভয়ই?
রাগ্গেরো তুরা

1
@ রাগেরোটুরা আমি যদি কোনও উত্স না পাই তবে আমি আর পারছি না এবং আমি এখনই সিপিইউ ডেটাশিট পড়ার মুডে নেই।
ওয়াইএসসি

@ রাগেরোতুরা সাধারণত ক্রমবর্ধমান অ্যাক্সেসের অর্থ এগিয়ে নেওয়া উচিত। সমস্ত আধা-শালীন মেমরি প্রিফেটররা ক্রমবর্ধমান অ্যাক্সেসটিকে ধরবে।
টুথব্রাশ

@ টুথব্রাশ, ধন্যবাদ সুতরাং, যদি আমি পিছনে লুপ করি, নীতিগতভাবে, এটি একটি পারফরম্যান্সের সমস্যা হতে পারে
রুগেরো তুরা

নীতিগতভাবে, কমপক্ষে কয়েকটি হার্ডওয়্যারে, যদি পুরো ভেক্টর ইতিমধ্যে এল 1 ক্যাশে না থাকে।
13:40

2

এই উদ্দেশ্যে আপনি কোনও ট্রান্সপোজেশন ছাড়াই বিপরীত পুনরুক্তি ব্যবহার করতে পারেন আপনার std::vector<float> vec:

float sum{0.f};
for (auto rIt = vec.rbegin(); rIt!= vec.rend(); ++rIt)
{
    sum += *rit;
}

বা স্ট্যান্ডার্ড অ্যালগরিদম ব্যবহার করে একই কাজ করুন:

float sum = std::accumulate(vec.crbegin(), vec.crend(), 0.f);

পারফরম্যান্স একই হতে হবে, কেবল আপনার ভেক্টরের বাইপাসের দিক পরিবর্তন করা


আমি ভুল হলে আমাকে সংশোধন করুন, তবে আমি মনে করি এটি ওপেন ব্যবহার করছে এমন ফোরচ স্টেটমেন্টের চেয়ে আরও দক্ষ, কারণ এটি একটি ওভারহেডের পরিচয় দেয়। ওয়াইএসসি সংখ্যার স্থায়িত্ব অংশ সম্পর্কে ঠিক।
সেফিরোথ

4
@ সেফিরোথ নং, যে কোনও অর্ধ-শালীন সংকলক সত্যিই যত্ন করে না আপনি কোনও রেঞ্জের জন্য লিখেছেন বা কোনও পুনরুক্তিকারী লিখেছেন কিনা।
ম্যাক্স ল্যাংফোফ

1
রিয়েল-ওয়ার্ল্ড পারফরম্যান্স স্থিরভাবে ক্যাশে / প্রিফেচিংয়ের কারণে এক হওয়ার নিশ্চয়তা দেয় না। ওপিতে এটি থেকে সাবধান হওয়া যুক্তিযুক্ত।
ম্যাক্স ল্যাংফোফ

1

যদি সংখ্যার স্থায়িত্ব দ্বারা আপনি নির্ভুলতা বোঝাতে চান, তবে হ্যাঁ, আপনি নির্ভুলতার সমস্যাগুলি শেষ করতে পারেন। ক্ষুদ্রতম মানগুলির বৃহত্তমের অনুপাত এবং ফলাফলটিতে নির্ভুলতার জন্য আপনার প্রয়োজনীয়তার উপর নির্ভর করে এটি সমস্যা হতে পারে বা নাও পারে।

আপনি যদি উচ্চ নির্ভুলতা পেতে চান তবে কাহান সংক্ষেপণ বিবেচনা করুন - এটি ত্রুটির ক্ষতিপূরণের জন্য অতিরিক্ত ভাসা ব্যবহার করে। রয়েছে pairwise সমষ্টি

নির্ভুলতা এবং সময়ের মধ্যে ট্রেড অফের বিশদ বিশ্লেষণের জন্য, এই নিবন্ধটি দেখুন

সি ++ 17 এর জন্য আপডেট করুন:

অন্য কয়েকটি উত্তর উল্লেখ করেছেন std::accumulate। সি ++ 17 যেহেতু এখানে এক্সিকিউশন পলিসি রয়েছে যা অ্যালগরিদমগুলিকে সমান্তরাল করতে দেয়।

এই ক্ষেত্রে

#include <vector>
#include <execution>
#include <iostream>
#include <numeric>

int main()
{  
   std::vector<double> input{0.1, 0.9, 0.2, 0.8, 0.3, 0.7, 0.4, 0.6, 0.5};

   double reduceResult = std::reduce(std::execution::par, std::begin(input), std::end(input));

   std:: cout << "reduceResult " << reduceResult << '\n';
}

এটি ননডেটারিস্টেমিকিক রাউন্ডিং ত্রুটির মূল্যে বড় ডেটাসেটগুলি দ্রুত সংশ্লেষ করা উচিত (আমি ধরে নিচ্ছি যে ব্যবহারকারী থ্রেড বিভাজন নির্ধারণ করতে সক্ষম হবে না)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.