Українська
Завдання
Відповідно до номера свого варіанта виконайте завдання обраного рівня складності.
Варіанти
Варіант 1. Змішування аудіодоріжок
1. Початковий рівень. Створити консольну програму, яка генерує дві аудіодоріжки по 10 000 000 відліків short (синусоїди 440 і 660 Гц з частотою дискретизації 44 100 Гц), змішує їх поелементним додаванням з насиченням скалярно та за допомогою Vector256.AddSaturate, перевіряє збіг результатів і виводить час обох варіантів і кількість обмежених відліків.
2. Базовий рівень. Створити консольну програму, яка генерує дві аудіодоріжки по 10 000 003 відліки short (синусоїди 440 і 660 Гц), запитує гучність кожної доріжки (від 0 до 2), перевіряє введення і змішує доріжки з масштабуванням і насиченням трьома способами: скалярно, Vector<T> і Vector256<T> з обробкою хвоста. Програма виводить таблицю «спосіб – час, мс – прискорення – збіг».
3. Високий рівень. Створити консольний застосунок mix, який приймає опції --input a.raw,b.raw (16-бітні відліки без заголовка), --gains 0.8,1.2, --output mix.raw, --mode scalar|vector|parallel і --help. Режим parallel ділить доріжки на блоки для Parallel.For і змішує кожен блок Vector256. Програма записує результат, виводить таблицю часу й прискорення всіх режимів і відсоток обмежених відліків; помилки аргументів і файлів різної довжини – у потік помилок з кодами завершення 1 і 2.
Варіант 2. Яскравість і контраст фото
1. Початковий рівень. Створити консольну програму, яка створює зображення у відтінках сірого 4000×3000 байтів (генератор із фіксованим зерном), збільшує яскравість на 40 з насиченням скалярно та за допомогою Vector256<byte> і Vector256.AddSaturate, перевіряє побайтний збіг і виводить час обох варіантів.
2. Базовий рівень. Створити консольну програму, яка запитує зміну яскравості (від −100 до 100) і коефіцієнт контрасту (від 0,5 до 2), перевіряє введення та обробляє зображення 6000×4000 байтів за формулою Vector256<short>, розширення Widen і звуження Narrow). Програма виводить час, прискорення та кількість пікселів, що відрізняються від еталона.
3. Високий рівень. Створити консольний застосунок photo, який приймає аргументи input.pgm output.pgm та опції --brightness, --contrast, --threads 1,2,4,8,16 і --help. Програма читає зображення PGM (P5), обробляє його скалярно, векторно (Vector256) і векторно з Parallel.For за рядками для кожної кількості потоків, перевіряє збіг результатів, виводить таблицю «спосіб – потоки – час –
Варіант 3. Пошук схожих текстів
1. Початковий рівень. Створити консольну програму, яка генерує 100 000 векторів ознак текстів розмірністю 384 (float, фіксоване зерно) і вектор запиту, обчислює косинусну подібність запиту до кожного вектора скалярним циклом і методом TensorPrimitives.CosineSimilarity, виводить індекс і подібність найбільш схожого тексту та час обох способів.
2. Базовий рівень. Створити консольну програму, яка запитує кількість векторів (від 1000 до 500 000) і розмірність (від 16 до 1024), перевіряє введення, генерує вектори й запит, знаходить 10 найбільш схожих векторів за косинусною подібністю (TensorPrimitives) і виводить таблицю «місце – індекс – подібність», час пошуку й перевірку першого місця скалярно.
3. Високий рівень. Створити консольний застосунок similar, який приймає опції --data <файл CSV> (рядок – назва тексту й числа вектора), --query <номер рядка>, --top <k>, --threads 1,2,4,8 і --help. Програма нормалізує всі вектори (TensorPrimitives.Norm, Divide), шукає топ-Parallel.For за блоками, виводить результати й таблицю часу з прискоренням. Помилки даних і опцій – у потік помилок з кодом завершення 1.
Варіант 4. Статистика біржових цін
1. Початковий рівень. Створити консольну програму, яка генерує 20 000 000 цін double випадковим блуканням від 100 (фіксоване зерно) і обчислює мінімум, максимум і середнє скалярним циклом та методами TensorPrimitives.Min, Max, Sum, виводячи результати й час обох способів.
2. Базовий рівень. Створити консольну програму, яка запитує кількість цін (від 1000 до 50 000 000), перевіряє введення, генерує ціни double випадковим блуканням від 100 (фіксоване зерно) та обчислює мінімум, максимум, середнє й стандартне відхилення трьома способами: скалярно, Vector256<double> з обробкою хвоста і TensorPrimitives. Програма виводить таблицю значень, часу й відносної різниці з еталоном.
3. Високий рівень. Створити застосунок pricestats з проєктом BenchmarkDotNet, який порівнює скалярну, Vector<T>, Vector256<T> і TensorPrimitives реалізації статистики біржових цін (мінімум, максимум, середнє, стандартне відхилення) для згенерованих масивів довжиною 1000, 100 000 і 10 000 000 (атрибут [Params], базовий метод Baseline = true). Окремий режим --file <CSV> читає ціни зі стовпця close, виводить статистику й ковзне середнє за 20 днів (векторно). Помилки файлу – у потік помилок з кодом 2.
Варіант 5. Множення матриць
1. Початковий рівень. Створити консольну програму, яка множить дві матриці double 1000×1000 (фіксоване зерно) порядками циклів ijk та ikj, виводить час обох порядків, GFLOPS (
2. Базовий рівень. Створити консольну програму, яка запитує розмір матриць Vector256<double>. Програма виводить таблицю «плитка – час, мс – GFLOPS» (медіана трьох запусків), позначає найкращу плитку і перевіряє результат порівнянням з порядком ikj.
3. Високий рівень. Створити консольний застосунок gemm, який множить дві випадкові матриці double розміром --n блочним алгоритмом з SIMD і Parallel.For за рядками плиток з опціями --blocks 16,32,64,128, --threads 1,2,4,8,16, --csv <файл> і --help. Для кожної пари «плитка – потоки» програма перевіряє результат з множенням порядком ikj (допуск
Варіант 6. Метод Гаусса
1. Початковий рівень. Створити консольну програму, яка розв’язує СЛАР 500×500 з випадковою матрицею й відомим розв’язком методом Гаусса з вибором головного елемента: послідовно та з Parallel.For для виключення рядків. Програма виводить час обох варіантів і максимальну похибку розв’язку.
2. Базовий рівень. Створити консольну програму, яка запитує розмір системи TensorPrimitives.MultiplyAdd) і векторно з Parallel.For. Програма виводить таблицю «спосіб – час – прискорення – похибка розв’язку – нев’язка
3. Високий рівень. Створити консольний застосунок gauss, який розв’язує СЛАР методом Гаусса з вибором головного елемента, виконуючи виключення рядків векторно й паралельно (Parallel.For), з опціями --n (випадкова система з відомим розв’язком) або --file <матриця CSV>, --threads, --min-rows <поріг паралельного виключення> і --help. Для малих залишків рядків виключення послідовне. Програма виводить перші 10 значень розв’язку, нев’язку, таблицю часу для кількостей потоків і найкращий поріг. Вироджена матриця (головний елемент менший за
Варіант 7. Частинки в симуляції
1. Початковий рівень. Створити консольну програму, яка моделює 1 000 000 частинок з координатами й швидкостями Vector3: на кожному кроці додає гравітацію до швидкості та швидкість до координат (
2. Базовий рівень. Створити консольну програму, яка запитує кількість частинок і кроків, перевіряє введення та моделює рух частинок під дією гравітації (на кожному кроці гравітація додається до швидкості, швидкість – до координат) двома способами: масив Vector3 (AoS) і окремі масиви координат float[] з оновленням Vector256 (SoA). Частинки, що впали нижче нуля, відбиваються (ConditionalSelect). Програма виводить кроки за секунду для обох способів і максимальну різницю координат.
3. Високий рівень. Створити консольний застосунок particles, який моделює рух частинок під дією гравітації з відбиттям від землі (швидкість і координати оновлюються на кожному кроці) з опціями --count, --steps, --mode aos|soa|soa-parallel, --threads, --snapshot <файл CSV> і --help. Режим aos – масив Vector3, soa – окремі масиви координат з Vector256, soa-parallel – ще й блоки для Parallel.For. Програма виводить таблицю «режим – потоки – кроків/с – прискорення», перевіряє збереження кількості частинок і записує координати перших 1000 частинок у CSV. Помилки – у потік помилок з кодом 1.
Варіант 8. Обчислення поліномів
1. Початковий рівень. Створити консольну програму, яка обчислює поліном степеня 8 з введеними коефіцієнтами для 10 000 000 значень Vector256<double>), виводить значення в трьох точках і час обох способів.
2. Базовий рівень. Створити консольну програму, яка запитує степінь (від 1 до 20) і коефіцієнти полінома, перевіряє введення та обчислює поліном для масиву Vector<double> і Vector256.FusedMultiplyAdd. Програма виводить таблицю часу й прискорення та максимальну відносну різницю результатів.
3. Високий рівень. Створити консольний застосунок horner, який приймає опції --coeffs 1,-2,0.5, --from, --to, --count, --threads 1,2,4,8, --output <CSV> і --help. Програма обчислює значення полінома й похідної векторно з Parallel.For за блоками, знаходить наближені корені за зміною знака, виводить таблицю часу для кількостей потоків і записує таблицю значень у CSV. Некоректні коефіцієнти – повідомлення в потік помилок і код 1.
Варіант 9. Фрактал Мандельброта
1. Початковий рівень. Створити консольну програму, яка обчислює множину Мандельброта 1600×1200 (до 500 ітерацій) скалярно та векторно Vector256<double> з маскою активних точок (LessThanOrEqual, ConditionalSelect), виводить загальну кількість ітерацій обох способів і час.
2. Базовий рівень. Створити консольну програму, яка запитує розмір зображення та максимальну кількість ітерацій, перевіряє введення, обчислює множину Мандельброта скалярно, векторно (Vector256<double> з маскою активних точок) і векторно з Parallel.For за рядками, перевіряє збіг кількості ітерацій для кожного пікселя і записує зображення PGM. Програма виводить таблицю «спосіб – час – прискорення».
3. Високий рівень. Створити консольний застосунок mandel, який обчислює множину Мандельброта векторно з маскою активних точок і Parallel.For за рядками та записує її у файл PGM (--output). Опції: --size 1920x1080, --center -0.5,0, --zoom, --iterations, --vector 128|256|512, --threads, --help. Програма перевіряє IsHardwareAccelerated для обраної ширини (інакше повідомлення й запасний скалярний шлях) і виводить таблицю часу для ширин векторів і кількостей потоків. Помилки аргументів – у потік помилок з кодом 1.
Варіант 10. Контрольна сума файлу
1. Початковий рівень. Створити консольну програму, яка читає файл, шлях до якого вводить користувач, і обчислює суму всіх байтів (ulong) скалярним циклом і векторно блоками Vector256<byte> з розширенням до ulong, виводячи обидві суми, розмір файлу й час.
2. Базовий рівень. Створити консольну програму, яка обчислює для файлу, шлях до якого вводить користувач, контрольну суму Флетчера-32 (дві суми за модулем 65 535) скалярно та векторно (блоки по 256 байтів з накопиченням у Vector256<uint>), перевіряє збіг сум, виводить їх у шістнадцятковому вигляді, швидкість обробки (МБ/с) обох способів і повідомлення, якщо файл не знайдено.
3. Високий рівень. Створити консольний застосунок checksum, який приймає шляхи до файлів або каталогу, опції --algorithm sum|fletcher32, --mode scalar|vector, --parallel (файли обробляються паралельно) і --help. Програма виводить таблицю «файл – розмір – сума – МБ/с», підсумок і порівняння режимів; файли без доступу пропускаються з повідомленням у потік помилок, а код завершення 2 означає, що хоча б один файл не оброблено.
Варіант 11. Теплопровідність 2D методом Якобі
1. Початковий рівень. Створити консольну програму, яка моделює теплопровідність у пластині 512×512 (верхня межа 100 °C, інші 0 °C) методом Якобі з п’ятиточковим шаблоном, виконує 2000 ітерацій послідовно та з Parallel.For за рядками, виводить температуру в центрі й час.
2. Базовий рівень. Створити консольну програму, яка моделює теплопровідність у пластині (верхня межа 100 °C, інші 0 °C) методом Якобі з п’ятиточковим шаблоном. Програма запитує розмір сітки й точність, перевіряє введення та виконує ітерації до збіжності трьома способами: скалярно, векторно (Vector256<double> для внутрішніх вузлів рядка) і векторно з Parallel.For, і виводить кількість ітерацій, температуру в центрі та таблицю часу й прискорення.
3. Високий рівень. Створити консольний застосунок heat, який моделює стаціонарну теплопровідність у квадратній пластині методом Якобі з п’ятиточковим шаблоном (векторно й з Parallel.For) до точності --eps. Опції: --size, --boundary 100,0,0,0 (температури меж), --threads 1,2,4,8,16, --output <PGM>, --help. Для кожної кількості потоків програма розв’язує задачу, перевіряє однаковість розв’язків, виводить таблицю «потоки – ітерації – час –
Варіант 12. Нормалізація ознак датасету
1. Початковий рівень. Створити консольну програму, яка генерує таблицю 1 000 000×16 ознак float (фіксоване зерно) і для кожного стовпця обчислює середнє й стандартне відхилення методами TensorPrimitives, перетворює значення на z-оцінки та виводить статистику перших трьох стовпців до й після перетворення.
2. Базовий рівень. Створити консольну програму, яка читає файл CSV з числовими стовпцями, шлях до якого вводить користувач, перевіряє дані, обчислює z-оцінки стовпців скалярно та векторно (Vector256<float>), записує результат у новий CSV і виводить таблицю «стовпець – середнє – відхилення» та час обох способів.
3. Високий рівень. Створити консольний застосунок zscore, який приймає опції --input, --output, --columns 1,3,5, --method zscore|minmax, --threads і --help. Стовпці обробляються паралельно (Parallel.ForEach), значення – векторно; пропущені значення замінюються середнім. Програма виводить таблицю статистики, час читання, обчислення й запису; некоректні рядки CSV – повідомлення з номером рядка в потік помилок і код 2.
Варіант 13. Підрахунок символів у тексті
1. Початковий рівень. Створити консольну програму, яка читає текстовий файл у байти й підраховує кількість пробілів скалярним циклом і векторно Vector128.Equals, ExtractMostSignificantBits і BitOperations.PopCount, виводячи обидві кількості й час.
2. Базовий рівень. Створити консольну програму, яка запитує шлях до файлу і символ ASCII, перевіряє введення та підраховує кількість цього символу, рядків і пробілів трьома способами: скалярно, Vector256<byte> з масками і методом MemoryExtensions.Count. Програма виводить таблицю «спосіб – кількість – час – прискорення».
3. Високий рівень. Створити консольний застосунок wcs, аналог утиліти wc, який приймає шляхи до файлів та опції -l, -w, -c, --vector 128|256, --help. Слова рахуються векторно за переходами «пробільний символ – непробільний» у бітовій масці (з урахуванням меж блоків). Програма виводить таблицю для кожного файлу й підсумок, перевіряє результат скалярною версією з опцією --verify; відсутній файл – повідомлення в потік помилок і код 1.
Варіант 14. Трансформація 3D-моделі
1. Початковий рівень. Створити консольну програму, яка генерує 2 000 000 вершин Vector3, будує матрицю Matrix4x4 з обертання навколо осі Y на введений кут, масштабу й перенесення та перетворює всі вершини методом Vector3.Transform, виводячи перші три вершини до й після перетворення та час.
2. Базовий рівень. Створити консольну програму, яка запитує кути обертання навколо осей X, Y, Z і перенесення, перевіряє введення та перетворює масив вершин двома способами: Vector3.Transform для масиву Vector3 і власною векторною реалізацією для масивів координат float[] на Vector256. Програма виводить час, прискорення й максимальну різницю координат.
3. Високий рівень. Створити консольний застосунок transform, який читає модель у форматі OBJ (рядки v x y z), приймає опції --rotate 0,45,0, --scale, --translate 1,0,0, --output <OBJ>, --mode vector3|vector256|parallel і --help. Програма зберігає інші рядки файлу без змін, виводить габаритний прямокутник моделі до й після перетворення та таблицю часу режимів; помилки формату – у потік помилок з номером рядка й кодом 2.
Варіант 15. Згортка сигналу ЕКГ
1. Початковий рівень. Створити консольну програму, яка генерує сигнал ЕКГ з шумом (2 000 000 відліків float) і застосовує FIR-фільтр ковзного середнього з 31 коефіцієнта скалярно та векторно (TensorPrimitives.Dot для кожного вікна), виводить максимальну різницю результатів і час.
2. Базовий рівень. Створити консольну програму, яка генерує сигнал ЕКГ з шумом, запитує довжину фільтра (непарне число від 3 до 255) і частоту зрізу, будує коефіцієнти низькочастотного FIR-фільтра з вікном Хеммінга, фільтрує сигнал скалярно, векторно (Vector256 за коефіцієнтами) і векторно з Parallel.For за блоками та виводить таблицю часу й максимальну різницю з еталоном.
3. Високий рівень. Створити консольний застосунок fir, який приймає опції --input <CSV відліків>, --taps, --cutoff, --sample-rate, --output <CSV>, --threads і --help. Програма фільтрує сигнал, знаходить R-піки (перевищення порогу після фільтрації) і обчислює частоту серцевих скорочень, виводить таблицю часу режимів і перевіряє збіг векторного результату зі скалярним. Помилки файлу й аргументів – у потік помилок з кодами 2 і 1.
Варіант 16. Відстані до складів
1. Початковий рівень. Створити консольну програму, яка генерує координати 10 складів і 1 000 000 магазинів на площині та для кожного магазину знаходить найближчий склад скалярно та векторно (координати магазинів у масивах float[], відстані до складу через Vector256), виводячи кількість магазинів кожного складу й час.
2. Базовий рівень. Створити консольну програму, яка запитує кількість складів і магазинів, перевіряє введення та призначає магазини найближчим складам трьома способами: скалярно, Vector256 з масками LessThan і ConditionalSelect для вибору мінімуму і векторно з Parallel.For. Програма перевіряє збіг призначень і виводить таблицю часу й середню відстань для кожного складу.
3. Високий рівень. Створити консольний застосунок nearest, який читає склади й магазини з файлів CSV (назва, x, y), приймає опції --stores, --warehouses, --output <CSV>, --capacity <k> (не більше --help. Програма виводить таблицю завантаження складів, сумарну відстань і час векторного пошуку; помилки файлів – у потік помилок з кодом 2.
Варіант 17. Скалярний добуток double
1. Початковий рівень. Створити консольну програму, яка обчислює скалярний добуток двох масивів з 5 000 001 числа double скалярно та за допомогою Vector<double> з обробкою хвоста, виводить Vector<double>.Count, обидва результати, відносну різницю й час.
2. Базовий рівень. Створити консольну програму, яка запитує довжину масивів, перевіряє введення та обчислює скалярний добуток чотирма способами: скалярно, Vector<double>, Vector512<double> (лише якщо Vector512.IsHardwareAccelerated, інакше повідомлення і Vector256) і TensorPrimitives.Dot. Програма виводить таблицю «спосіб – ширина – час – прискорення – різниця».
3. Високий рівень. Створити застосунок dotbench з BenchmarkDotNet, який порівнює скалярну, Vector<T>, Vector256<T>, Vector512<T> (із запасним шляхом) і TensorPrimitives реалізації скалярного добутку для довжин 16, 1000, 1 000 000 з [DisassemblyDiagnoser]. Режим --test перевіряє реалізації на довжинах 0, 1, 7, 8, 9, 1023; розбіжність – у потік помилок з кодом 1. Звіт має містити запуски зі змінними DOTNET_EnableAVX512=0 та DOTNET_EnableAVX2=0.
Варіант 18. Сепія для кадрів відео
1. Початковий рівень. Створити консольну програму, яка генерує кадр RGB 1920×1080 (окремі масиви каналів float), застосовує фільтр сепії скалярно та векторно (Vector256<float>, обмеження Vector256.Min до 255) і виводить час, прискорення та максимальну різницю каналів.
2. Базовий рівень. Створити консольну програму, яка запитує кількість кадрів (від 1 до 300) і силу ефекту (від 0 до 1), перевіряє введення та обробляє кадри сепією з інтерполяцією між оригіналом і сепією скалярно й векторно (ConditionalSelect для пікселів, яскравіших за поріг), виводячи кадри за секунду обох способів.
3. Високий рівень. Створити консольний застосунок sepia, який читає послідовність файлів PPM з каталогу, приймає опції --strength, --threads, --mode scalar|vector|parallel, --output <каталог> і --help. Кадри обробляються векторно, а в режимі parallel – ще й паралельно. Програма виводить кадри за секунду, загальний час і перевіряє побайтний збіг векторного й скалярного результату для першого кадру; помилки – у потік помилок з кодом 2.
Варіант 19. Червоно-чорний метод Гаусса–Зейделя
1. Початковий рівень. Створити консольну програму, яка розв’язує рівняння Лапласа на сітці 256×256 (верхня межа 100, інші 0) методом Гаусса–Зейделя послідовно та червоно-чорним методом з Parallel.For за рядками до точності
2. Базовий рівень. Створити консольну програму, яка розв’язує рівняння Лапласа на квадратній сітці (верхня межа 100, інші 0). Програма запитує розмір сітки й точність, перевіряє введення та порівнює методи Якобі, Гаусса–Зейделя й паралельний червоно-чорний (Parallel.For за рядками) за кількістю ітерацій, часом і максимальною різницею розв’язків, виводячи вирівняну таблицю.
3. Високий рівень. Створити консольний застосунок redblack, який розв’язує рівняння Лапласа на квадратній сітці (верхня межа 100, інші 0) паралельним червоно-чорним методом SOR з опціями --size, --eps, --omega <від 1 до 2>, --threads 1,2,4,8,16, --csv <файл> і --help. Для кожної кількості потоків програма виводить таблицю «потоки – ітерації – час – omega серед 1,0; 1,5; 1,8; 1,9 і записує CSV. Розбіжність розв’язків для різних кількостей потоків – повідомлення в потік помилок і код 2.
Варіант 20. Гістограма байтів
1. Початковий рівень. Створити консольну програму, яка читає файл і будує гістограму 256 значень байтів скалярно та паралельно (Parallel.For з локальною гістограмою для кожного блоку), виводить 10 найчастіших байтів і час обох способів.
2. Базовий рівень. Створити консольну програму, яка запитує шлях до файлу, будує гістограму трьома способами: наївно, «чотири лічильники» (розгортання циклу на чотири масиви) і паралельно за блоками, перевіряє збіг гістограм і виводить таблицю «спосіб – час – МБ/с», а також ентропію файлу в бітах на байт.
3. Високий рівень. Створити консольний застосунок bytehist, який приймає шляхи до файлів, опції --threads, --top <k>, --csv <файл>, --compare і --help. Для кожного файлу програма будує гістограму паралельно з векторним підрахунком окремих значень (маски Vector256.Equals і PopCount для заданого набору байтів), виводить ентропію, топ-
Варіант 21. Задача про рюкзак
1. Початковий рівень. Створити консольну програму, яка розв’язує задачу про рюкзак 0/1 для 200 предметів (фіксоване зерно) і місткості 100 000 динамічним програмуванням з одним рядком таблиці, оновлюючи рядок скалярно, і виводить найбільшу цінність та час.
2. Базовий рівень. Створити консольну програму, яка запитує кількість предметів і місткість, перевіряє введення та розв’язує задачу про рюкзак двома способами: скалярним оновленням рядка ДП і векторним (Vector256<int>: зсунутий рядок плюс цінність, Vector256.Max з поточним рядком, новий рядок в окремому масиві). Програма виводить цінність, збіг результатів і час.
3. Високий рівень. Створити консольний застосунок knapsack, який читає предмети з файлу CSV (назва, вага, цінність), приймає опції --capacity, --mode scalar|vector, --items (вивести вибрані предмети) і --help. Для відновлення набору предметів програма зберігає бітові маски рішень, виводить таблицю вибраних предметів, загальні вагу й цінність і час; некоректні рядки CSV – повідомлення з номером рядка в потік помилок і код 2.
Варіант 22. LU-розклад
1. Початковий рівень. Створити консольну програму, яка виконує LU-розклад (метод Дуліттла без перестановок) матриці 600×600 з діагональною перевагою послідовно та з Parallel.For для оновлення рядків і виводить час обох варіантів і похибку відновлення
2. Базовий рівень. Створити консольну програму, яка запитує розмір матриці (від 100 до 2000), перевіряє введення та виконує LU-розклад скалярно, векторно (TensorPrimitives.MultiplyAdd для оновлення рядка) і векторно з Parallel.For, виводячи таблицю часу, прискорення й похибки відновлення.
3. Високий рівень. Створити консольний застосунок lu, який приймає опції --n, --block <розмір блоку>, --threads 1,2,4,8,16 і --help. Програма виконує блочний LU-розклад (панель стовпців і оновлення решти матриці блоками), порівнює його з неблочним, розв’язує систему з отриманими
Варіант 23. Порівняння зображень
1. Початковий рівень. Створити консольну програму, яка генерує два зображення у відтінках сірого 4000×3000 байтів, що відрізняються шумом, і обчислює суму абсолютних різниць (SAD) скалярно та векторно (Vector256.Max і Vector256.Min для модуля різниці байтів) з виведенням обох сум і часу.
2. Базовий рівень. Створити консольну програму, яка генерує кадр 1920×1080 і фрагмент 32×32 з нього з доданим шумом, шукає позицію фрагмента в кадрі за найменшою SAD (векторно для кожного рядка фрагмента) і виводить знайдену позицію, SAD і час скалярного й векторного пошуку.
3. Високий рівень. Створити консольний застосунок findframe, який приймає файли PGM --image, --template, опції --step, --threads, --top <k> і --help. Програма шукає Parallel.For за рядками, виводить таблицю «позиція – SAD» та порівняння часу зі скалярною версією; шаблон, більший за зображення, і помилки формату – повідомлення в потік помилок і код 2.
Варіант 24. Ймовірності в медичних тестах
1. Початковий рівень. Створити консольну програму, яка для 10 000 000 пацієнтів з випадковою апріорною ймовірністю хвороби обчислює апостеріорну ймовірність за формулою Байєса при позитивному тесті (чутливість 0,95, специфічність 0,9) скалярно та векторно Vector256<double>, виводячи середню ймовірність і час.
2. Базовий рівень. Створити консольну програму, яка запитує чутливість і специфічність тесту (від 0,5 до 1), перевіряє введення та обчислює апостеріорні ймовірності для позитивних і негативних результатів (ConditionalSelect за масивом результатів) скалярно, Vector<double> і TensorPrimitives, виводячи таблицю часу та кількість пацієнтів з імовірністю понад 0,5.
3. Високий рівень. Створити консольний застосунок bayes, який читає файл CSV пацієнтів (ідентифікатор, апріорна ймовірність, результати кількох тестів), приймає опції --tests <файл параметрів тестів>, --threshold, --output і --help. Програма послідовно застосовує формулу Байєса для кожного тесту векторно, записує результат, виводить розподіл ймовірностей за десятьма інтервалами та час; некоректні ймовірності – повідомлення в потік помилок і код 2.
Варіант 25. Координати GPS
1. Початковий рівень. Створити консольну програму, яка генерує 5 000 000 точок GPS у Європі та обчислює відстань від кожної до Брюсселя (50,85° пн. ш., 4,35° сх. д.) за формулою гаверсинуса скалярно та векторно (Vector256<double>, Vector256.Sin, Vector256.Cos), виводячи середню відстань і час.
2. Базовий рівень. Створити консольну програму, яка генерує 5 000 000 точок GPS у Європі, запитує координати центру й радіус, перевіряє введення та підраховує точки в межах радіуса за формулою гаверсинуса векторно в float і double, виводячи кількість точок, максимальну різницю відстаней float і double у метрах і час обох варіантів.
3. Високий рівень. Створити консольний застосунок geo, який читає трек GPS з файлу CSV (час, широта, довгота), приймає опції --precision float|double, --output, --stop-speed і --help. Програма векторно обчислює відстані між сусідніми точками, загальну довжину треку, швидкості й зупинки, виводить звіт і порівняння похибок float/double; некоректні координати – повідомлення з номером рядка в потік помилок і код 2.
Варіант 26. Модель ціни опціонів
1. Початковий рівень. Створити консольну програму, яка генерує 1 000 000 опціонів (ціна активу, страйк, строк, волатильність) і обчислює ціну європейського опціону call за формулою Блека–Шоулза скалярно, виводячи середню ціну й кількість опціонів за секунду.
2. Базовий рівень. Створити консольну програму, яка запитує кількість опціонів і безризикову ставку, перевіряє введення та обчислює ціни call і put за формулою Блека–Шоулза скалярно та векторно (Vector256<double> з наближенням нормального розподілу поліномом), перевіряє паритет put–call і виводить мільйони опціонів за секунду для обох способів.
3. Високий рівень. Створити консольний застосунок blackscholes, який приймає опції --count, --rate, --precision float|double, --threads 1,2,4,8,16, --input <CSV опціонів> і --help. Програма обчислює ціни й «грецькі» дельта і вега векторно з Parallel.For, виводить таблицю «потоки – опціонів/с – float/double і записує результати для вхідного файлу. Помилки – у потік помилок з кодом 1.
Варіант 27. Розріджені матриці CSR
1. Початковий рівень. Створити консольну програму, яка будує розріджену матрицю 1 000 000×1 000 000 з 5 ненульовими елементами в рядку у форматі CSR і множить її на вектор послідовно та з Parallel.For за рядками, виводячи норму результату й час.
2. Базовий рівень. Створити консольну програму, яка запитує розмір матриці й кількість ненульових елементів у рядку, перевіряє введення, будує матрицю CSR, транспонує її (підрахунок елементів стовпців і префіксна сума) та перевіряє рівність
3. Високий рівень. Створити консольний застосунок spmv, який читає матрицю у форматі Matrix Market (.mtx), приймає опції --iterations, --threads 1,2,4,8,16, --partition rows|nnz і --help. Програма виконує множення на вектор з розбиттям рядків порівну або за кількістю ненульових елементів, виводить таблицю часу, прискорення й дисбалансу навантаження потоків; помилки формату – у потік помилок з кодом 2.
Варіант 28. Хвильове рівняння 1D
1. Початковий рівень. Створити консольну програму, яка моделює коливання струни з 1 000 000 вузлів явною різницевою схемою (три шари double) протягом 1000 кроків скалярно та векторно (Vector256<double> для внутрішніх вузлів) і виводить енергію струни на початку й наприкінці та час.
2. Базовий рівень. Створити консольну програму, яка моделює коливання струни (одновимірне хвильове рівняння) явною різницевою схемою з трьома шарами double. Програма запитує кількість вузлів, кроків і число Куранта (не більше 1), перевіряє введення та виконує моделювання скалярно, векторно (Vector256<double>) і векторно з Parallel.For за блоками, перевіряє збіг результатів і виводить таблицю часу й прискорення.
3. Високий рівень. Створити консольний застосунок wave, який моделює коливання струни (одновимірне хвильове рівняння) явною схемою векторно з Parallel.For і досліджує слабку масштабованість: кількість вузлів (--nodes-per-thread на потік) зростає пропорційно кількості потоків. Опції --steps, --threads 1,2,4,8,16, --csv <файл>, --help. Програма виводить таблицю «потоки – вузлів – час – ефективність слабкої масштабованості», записує CSV і перевіряє стійкість схеми; помилки – у потік помилок з кодом 1.
Варіант 29. Спектр звуку
1. Початковий рівень. Створити консольну програму, яка генерує сигнал 60 с з частотою 48 000 Гц, ділить його на кадри по 4096 відліків і множить кожен кадр на вікно Ганна скалярно та методом TensorPrimitives.Multiply, виводячи енергію перших трьох кадрів і час.
2. Базовий рівень. Створити консольну програму, яка генерує звуковий сигнал, запитує розмір кадру (степінь двійки від 256 до 16 384), перекриття (0–75 %) і тип вікна (Ганна, Хеммінга, Блекмана), перевіряє введення, ділить сигнал на кадри й множить їх на вікно векторно, обчислює середньоквадратичне значення кожного кадру (TensorPrimitives.Norm) і виводить 5 найгучніших кадрів та час.
3. Високий рівень. Створити застосунок frames з BenchmarkDotNet, який порівнює скалярну, Vector256 і TensorPrimitives підготовку кадрів для розмірів 1024 і 16 384 та режим --input <файл WAV PCM 16 біт> з опціями --frame, --overlap, --window і --help, що записує енергії кадрів у CSV. Інший формат WAV – помилка з кодом 2.
Варіант 30. Автовекторизація JIT
1. Початковий рівень. Створити консольну програму, яка сумує масив int з 10 000 000 елементів циклом for, foreach, LINQ Sum і Vector256, виводячи результати й час кожного способу.
2. Базовий рівень. Створити консольну програму, яка порівнює час п’яти форм циклу над масивом float (індекс і Length, індекс і збережена довжина, Span<T>, foreach, розгортання на чотири акумулятори) і векторної версії, виводить таблицю «форма – час – прискорення».
3. Високий рівень. Створити застосунок jitloops з BenchmarkDotNet і [DisassemblyDiagnoser], який порівнює форми циклів суми, пошуку максимуму й копіювання масивів з векторними версіями. Режим --report знаходить у файлі *-asm.md векторні (ymm) і скалярні (ss, sd) інструкції кожного методу й виводить таблицю; відсутній файл – повідомлення в потік помилок і код 2.
Порядок виконання та захисту роботи
- Опрацювати теоретичні відомості та приклади розв’язання завдань.
- Запустити приклад «Можливості процесора» на своєму ПК; для свого варіанта визначити, які операції можна векторизувати, де потрібні маски, як обробити хвіст і які частини даних можна обробляти паралельно.
- Створити в JetBrains Rider консольний проєкт; реалізувати скалярну версію, векторну версію (за потреби з пакетом
System.Numerics.Tensors) і перевірку збігу результатів з допуском для дійсних чисел на довжинах 0, 1,Count - 1,Count + 1і великій. - Виміряти час у конфігурації Release (прогрівання, медіана запусків або BenchmarkDotNet), обчислити прискорення від SIMD і від потоків; перевірити запасний шлях з
DOTNET_EnableAVX2=0. - Продемонструвати роботу програми, пояснити код і результати вимірювань, відповісти на питання.