سؤال

أنا مثل ناقلات الكثير.إنهم أنيق وسريع.ولكن أنا أعرف هذا الشيء يسمى valarray موجود.لماذا يمكنني استخدام valarray بدلا من ناقل?أنا أعرف valarrays بعض نحوي السكر, ولكن بخلاف ذلك, عندما هي مفيدة ؟

هل كانت مفيدة؟

المحلول

والمقصود

و(المصفوفات القيمة) Valarrays لجلب بعض من سرعة فورتران إلى C ++. هل لا تجعل valarray من مؤشرات ذلك المجمع يمكن أن تجعل افتراضات حول رمز وتحسين بطريقة أفضل. (السبب الرئيسي الذي فورتران سريعة جدا هو أنه لا يوجد أي نوع مؤشر لذلك يمكن أن يكون هناك التعرج المؤشر.)

لدينا

وValarrays أيضا الطبقات التي تسمح لك لشريحة عنها بطريقة سهلة إلى حد معقول على الرغم من أن جزءا من معيار يمكن استخدام أكثر قليلا من العمل. تغيير حجم منهم هو مدمر وأنها تفتقر المكررات.

وهكذا، إذا كان في الأرقام التي تعمل مع والراحة ليس كل ما valarrays استخدام مهم. خلاف ذلك، وناقلات هي مجرد الكثير أكثر ملاءمة.

نصائح أخرى

وvalarray هو نوع من يتيم التي ولدت في المكان الخطأ في الوقت الخطأ. انها محاولة لتحسين، وتحديدا إلى حد ما عن الآلات التي كانت تستخدم في الرياضيات الثقيلة عندما كان مكتوب - على وجه التحديد، ناقلات المعالجات مثل Crays

لمعالج ناقلات، ما أردت عموما القيام به هو تطبيق عملية واحدة إلى مجموعة بأكملها، ثم تطبيق العملية التالية للمجموعة بأكملها، وهلم جرا حتى كنت فعلت كل ما يلزم القيام به.

وإلا إذا كنت تتعامل مع صفائف صغيرة نسبيا، مع ذلك، أنه يميل إلى العمل بشكل سيئ مع التخزين المؤقت. على معظم الآلات الحديثة، ما كنت تفضل عموما (قدر الإمكان) سيكون لتحميل جزء من مجموعة، القيام بكل العمليات على ذلك وأنت تسير ل، ثم الانتقال إلى الجزء التالي من الصفيف.

ويفترض valarray أيضا إلى القضاء على أي إمكانية التعرج، والتي (نظريا على الأقل) يتيح للمترجم تحسين سرعة لأنها أكثر حرية لتخزين القيم في السجلات. في الواقع، ومع ذلك، وأنا لست على الإطلاق متأكد من أن أي تطبيق حقيقي يستفيد من هذا إلى أي درجة كبيرة. وأظن انها بالأحرى نوع الدجاجة والبيضة من المشكلة - دون دعم مترجم أنها لم تصبح شعبية، وطالما انها ليست شعبية، لا أحد سوف يذهب إلى عناء العمل على مترجم لدعم ذلك <. / P>

وهناك أيضا محيرة (حرفيا) مجموعة من الطبقات الثانوية للاستخدام مع valarray. تحصل slice، slice_array، gslice وgslice_array للعب مع قطعة من valarray، وجعلها تتصرف مثل مجموعة متعددة الأبعاد. يمكنك أيضا الحصول على mask_array ب "قناع" عملية (مثل إضافة عناصر في العاشر إلى y، ولكن فقط في المواقف حيث z غير صفرية). لجعل أكثر من استخدام تافهة من valarray، عليك أن تتعلم الكثير عن هذه الفئات الفرعية، وبعضها معقد جدا وليس فيها ما يبدو (على الأقل بالنسبة لي) موثقة بشكل جيد للغاية.

وخلاصة القول: حين أن لديها لحظات من التألق، ويمكن أن تفعل بعض الأشياء جميلة بدقة، وهناك أيضا بعض أسباب وجيهة جدا أنه (وبالتأكيد تقريبا البقاء) غامضة

وتحرير (بعد ثماني سنوات، في عام 2017): أصبح بعض السابقة عفا عليها الزمن إلى حد ما على الأقل. على سبيل المثال واحد، قامت إنتل نفذت نسخة محسنة من valarray للمترجم لهم. ويستخدم إنتل المتكاملة أداء البدائيون (إنتل IPP) لتحسين الأداء. على الرغم من أن تحسين الأداء المحدد يختلف بلا شك، وهو اختبار سريع مع رمز بسيط يظهر حول 2: تحسين 1 في السرعة مقارنة إلى رمز متطابقة جمعتها مع التنفيذ "القياسية" من valarray

وهكذا، بينما أنا لست مقتنعا تماما أن المبرمجين C ++ سيتم البدء في استخدام valarray بأعداد كبيرة، وهناك ما لا يقل عن بعض الظروف التي يمكن أن توفر تحسين سرعة.

وخلال توحيد C ++ 98، تم تصميم valarray للسماح نوعا من الحسابات الرياضية السريعة. ومع ذلك، في ذلك الوقت اخترع تود VELDHUIZEN قوالب التعبير وخلق مداهمات ++ ، واخترعت تقنيات مشابهة قالب الفوقية ، الأمر الذي جعل valarrays حد كبير عفا عليها الزمن حتى قبل أن صدر هذا المعيار. IIRC، مقدم الاقتراح الأصلي (ق) من valarray التخلي عليه في منتصف الطريق إلى توحيد، والتي (إذا كان هذا صحيحا) لم تساعد في ذلك سواء.

وISTR أن السبب الرئيسي هو عدم إزالته من المعيار هو أن لا أحد أخذ الوقت لتقييم هذه المسألة بدقة وكتابة مقترح لحذفها.

يرجى أن نضع في اعتبارنا، بيد أن كل هذا تذكرت غامضة الإشاعات. خذ هذا مع حبة الملح، ونأمل شخص ما يصحح أو يؤكد ذلك.

أنا أعرف valarrays بعض نحوي السكر

يجب أن أقول أنني لا أعتقد std::valarrays لدينا ما يكفي من السكر النحوية.جملة مختلفة ، ولكن لن أقول الفرق "السكر". API غريب.قسم std::valarrays في C++ لغة البرمجة يذكر أن هذا غير عادي API و حقيقة أنه منذ std::valarrays ومن المتوقع أن يكون الأمثل للغاية ، أي رسائل خطأ تحصل أثناء استخدامها المحتمل أن تكون غير بديهية.

من باب الفضول قبل نحو سنة حرض std::valarray ضد std::vector.أنا لم يعد لدينا قانون أو نتائج دقيقة (على الرغم من أنه لا ينبغي أن يكون من الصعب الكتابة الخاصة بك).باستخدام دول مجلس التعاون الخليجي أنا هل الحصول على القليل من الأداء فائدة عند استخدام std::valarray بسيطة الرياضيات ، ولكن ليس من أجل بلدي تطبيقات لحساب الانحراف المعياري (وبطبيعة الحال ، الانحراف المعياري ليس معقد بقدر الرياضيات يذهب). وأظن أن العمليات على كل عنصر في مجموعة كبيرة std::vector لعب بشكل أفضل مع مخابئ من العمليات على std::valarrays. (ملاحظة, النصيحة التالية من musiphil, لقد تمكنت من الحصول على ما يقرب من مطابقة الأداء من vector و valarray).

في النهاية قررت استخدام std::vector مع إيلاء اهتمام وثيق إلى أشياء مثل تخصيص الذاكرة المؤقتة إنشاء الكائن.


سواء std::vector و std::valarray تخزين البيانات في كتلة متجاورة.ومع ذلك ، فإنها الوصول إلى تلك البيانات باستخدام أنماط مختلفة ، والأهم من ذلك ، API std::valarray تشجع وصول مختلف أنماط من API std::vector.

بالنسبة الانحراف المعياري سبيل المثال ، في خطوة معينة كنت بحاجة إلى العثور على مجموعة يعني الفرق بين كل عنصر من عناصر قيمة يعني.

عن std::valarray, لقد فعلت شيئا مثل:

std::valarray<double> original_values = ... // obviously I put something here
double mean = original_values.sum() / original_values.size();
std::valarray<double> temp(mean, original_values.size());
std::valarray<double> differences_from_mean = original_values - temp;

ربما كنت أكثر ذكاء مع std::slice أو std::gslice.لقد مر أكثر من خمس سنوات حتى الآن.

بالنسبة std::vector, لقد فعلت شيئا على غرار:

std::vector<double> original_values = ... // obviously, I put something here
double mean = std::accumulate(original_values.begin(), original_values.end(), 0.0) / original_values.size();

std::vector<double> differences_from_mean;
differences_from_mean.reserve(original_values.size());
std::transform(original_values.begin(), original_values.end(), std::back_inserter(differences_from_mean), std::bind1st(std::minus<double>(), mean));

اليوم بالتأكيد أود أن أكتب هذا بشكل مختلف.إذا أي شيء آخر ، وأود أن الاستفادة من C++11 lambdas.

فمن الواضح أن هذين قصاصات من التعليمات البرمجية تفعل أشياء مختلفة.لأحد ، std::vector على سبيل المثال لا تجعل وسيطة جمع مثل std::valarray على سبيل المثال لا.ومع ذلك, أعتقد أنه من العدل المقارنة بينهما لأن الاختلافات ترتبط الاختلافات بين std::vector و std::valarray.

عندما كتبت هذا الجواب ، كنت أظن أن طرح قيمة عناصر من اثنين std::valarrays (السطر الأخير في std::valarray على سبيل المثال) سيكون أقل ذاكرة التخزين المؤقت الصديقة من المقابلة خط في std::vector على سبيل المثال (الذي يحدث أيضا أن يكون السطر الأخير).

اتضح ذلك أن

std::valarray<double> original_values = ... // obviously I put something here
double mean = original_values.sum() / original_values.size();
std::valarray<double> differences_from_mean = original_values - mean;

يفعل الشيء نفسه كما std::vector سبيل المثال ، قد متطابقة تقريبا الأداء.في النهاية السؤال هو الذي API كنت تفضل ذلك.

وكان من المفترض valarray السماح لبعض FORTRAN تجهيز ناقلات الخير كشط على C ++. بطريقة أو بأخرى في دعم مترجم الضروري أبدا حدث فعلا.

والكتب Josuttis تحتوي على بعض مثيرة للاهتمام (تحط إلى حد ما) التعليق على valarray (<لأ href = "http://books.google.co.uk/books؟id=n9VEG2Gp5pkC&lpg=PA547&ots=Rdj8kmcaTT&dq=Josuttis٪20valarray&pg=PA547# ت = onepage وف = & F = كاذبة "يختلط =" noreferrer "> هنا و <لأ href =" http://books.google.co.uk/books؟id=EotSAwuBkJoC&lpg=PA342&ots=iwL1E65kdd&dq=Josuttis٪20valarray&pg = PA342 # ت = onepage وف = & F = كاذبة "يختلط =" noreferrer "> هنا ).

ولكن، وإنتل يبدو الآن أن إعادة النظر valarray في الإصدارات مترجم الأخيرة الخاصة بهم (انظر على سبيل المثال <لأ href = "http://sc.tamu.edu/help/intel/tutorial/compiler_2.pdf" يختلط = "noreferrer" > شريحة 9 )؛ هذا تطورا مثيرا للاهتمام نظرا إلى أن 4 في اتجاه مجموعة التعليمات SIMD SSE بهم على وشك أن انضم بنسبة 8 في اتجاه AVX و 16 في اتجاه وتعليمات لارابي وفي مصلحة قابلية انها سوف المرجح أن تكون أفضل بكثير لرمز مع فكرة مجردة مثل valarray من (مثلا) intrinsics.

ولقد وجدت باستخدام واحد جيد للvalarray. انها لاستخدام valarray تماما مثل المصفوفات نمباي.

auto x = linspace(0, 2 * 3.14, 100);
plot(x, sin(x) + sin(3.f * x) / 3.f + sin(5.f * x) / 5.f);

ويمكننا تنفيذ أعلى مع valarray.

valarray<float> linspace(float start, float stop, int size)
{
    valarray<float> v(size);
    for(int i=0; i<size; i++) v[i] = start + i * (stop-start)/size;
    return v;
}

std::valarray<float> arange(float start, float step, float stop)
{
    int size = (stop - start) / step;
    valarray<float> v(size);
    for(int i=0; i<size; i++) v[i] = start + step * i;
    return v;
}

string psstm(string command)
{//return system call output as string
    string s;
    char tmp[1000];
    FILE* f = popen(command.c_str(), "r");
    while(fgets(tmp, sizeof(tmp), f)) s += tmp;
    pclose(f);
    return s;
}

string plot(const valarray<float>& x, const valarray<float>& y)
{
    int sz = x.size();
    assert(sz == y.size());
    int bytes = sz * sizeof(float) * 2;
    const char* name = "plot1";
    int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
    ftruncate(shm_fd, bytes);
    float* ptr = (float*)mmap(0, bytes, PROT_WRITE, MAP_SHARED, shm_fd, 0);
    for(int i=0; i<sz; i++) {
        *ptr++ = x[i];
        *ptr++ = y[i];
    }

    string command = "python plot.py ";
    string s = psstm(command + to_string(sz));
    shm_unlink(name);
    return s;
}

وأيضا، نحن بحاجة النصي الثعبان.

import sys, posix_ipc, os, struct
import matplotlib.pyplot as plt

sz = int(sys.argv[1])
f = posix_ipc.SharedMemory("plot1")
x = [0] * sz
y = [0] * sz
for i in range(sz):
    x[i], y[i] = struct.unpack('ff', os.read(f.fd, 8))
os.close(f.fd)
plt.plot(x, y)
plt.show()

والمعيار C ++ 11 يقول:

<اقتباس فقرة>   يتم تعريف

والطبقات valarray مجموعة أن تكون خالية من بعض أشكال   التعرج، مما يسمح العمليات على هذه الفئات ليكون الأمثل.

وانظر C ++ 11 26.6.1-2.

والأمراض المنقولة جنسيا :: المقصود valarray للمهام الثقيلة رقمية، مثل ديناميات الموائع الحسابية أو الحاسوبية هيكل الديناميات، التي لديك صفائف مع الملايين، وأحيانا عشرات الملايين من العناصر، ويمكنك تكرار عليها في حلقة مع الملايين أيضا من timesteps. ربما اليوم الأمراض المنقولة جنسيا :: ناقلات لديه أداء مشابه ولكن، قبل نحو 15 عاما، كان valarray إلزامية تقريبا إذا أردت كتابة حلالا رقمية فعالة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top