ONE PROJECT, DEEPER UNDERSTANDING

把一件小事,做得可解释。

Reduction Lab 从数组求和开始,逐步加入正确性合同、并行、测量和加速器映射。它贯穿主线,不需要同时开启三个厂商项目。

下载 learner starter ↓先理解 reduction →

starter 可编译,但核心函数刻意保留 LEARNER_TODO,初始测试必须失败。学习者完成代码后再验收。

Reduction Lab — learner starter

This is a fresh learner exercise, not a completed project. reduction.cpp deliberately reports LEARNER_TODO; the initial complete tests must fail. Build success is only a scaffold check. Save your implementation in a separate learner directory; keep the provided starter and its evidence intact.

First entry and file roles

Enter after G0 and SYS-00 fixed-width interfaces. Reuse 16.4’s placeholder and discarded-value reading for the existing logic_error and (void) lines. This README specifies the project contract, build commands and tasks; chapters own the C++ teaching.

File Role and first use
reduction.hpp Learner interface: first read sum_sequential; sum_parallel is a later task.
reduction.cpp Unfinished learner starter. Implement sequential first in your copy; keep parallel explicitly unfinished until its phase.
your sequential_tests.cpp Your first, independently written fixed-input and rejection checks. It calls sequential only.
tests.cpp Provided full acceptance harness. Its verify function also calls parallel, so it cannot turn green at the sequential milestone.
benchmark.cpp Later measurement harness, after both implementations pass correctness and its timing prerequisite.
CMakeLists.txt Provided build configuration. Read the basic target syntax in 17, then the project-specific command table below.

Contract

1 · Sequential work with a runnable check of your own

Read the contract and sequential declaration, write predictions, then implement only sequential in your learner copy. Create your own sequential_tests.cpp using the independently written expectation and registration checks from 18.1–18.2. Start with empty input, one element, zeros, mixed signs, both allowed value endpoints, a value just outside each endpoint, and the allowed length boundary. Give each test an explicit expected result or expected rejection. Do not call sum_parallel in this first harness.

Once you have written those two learner files, this is the standalone build/run path from their directory:

clang++ -std=c++20 -Wall -Wextra -Wpedantic -Werror -pthread reduction.cpp sequential_tests.cpp -o sequential_tests
./sequential_tests

This command is a task instruction, not a claim that a sequential_tests.cpp already exists or that your implementation passed. Keep the main function in your test file; reduction.cpp supplies the implementation. The original complete tests.cpp and learner_correctness CTest target still call the unfinished parallel function; their expected failure does not invalidate a separately demonstrated sequential milestone, and must not be hidden by deleting checks.

2 · Parallel and random cases at their own entry points

Before adding random tests, complete the independent Chapter 30: seeded-input-contract and its same-source small program. Then apply that interface reading to this project’s seed 20260905 and interval [-1000000,1000000]. Keep the fixed boundary cases and save generated input data; do not treat the word “seed” as sufficient preparation to read the harness.

Before parallel work, complete Chapter 25’s thread state and capture contracts and Chapter 31’s partitioning. Start with the assigned fixed eight-element/two-task prototype, then generalize to the bounded worker range. Draw partitions, compare against your verified sequential function, and include empty tasks and more workers than elements. The provided TODO is not a completed answer.

Only read and run the full tests.cpp at the complete acceptance stage: both implementations, random-input reading, and NET N3’s exception/what/cerr usage must be available. The existing rejection wrapper and (void) calls remain; use 16.4 when reading them. Downloading a harness earlier does not require predicting every line at the first sequential task.

3 · Full build and acceptance

After the complete-harness prerequisites, compile the existing full target directly:

clang++ -std=c++20 -Wall -Wextra -Wpedantic -Werror -pthread reduction.cpp tests.cpp -o reduction_tests
./reduction_tests

An unimplemented starter reports LEARNER_TODO. With CMake installed, the provided full build commands are:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build
ctest --test-dir build --output-on-failure
cmake -S . -B build-release -DCMAKE_BUILD_TYPE=Release
cmake --build build-release
./build-release/reduction_bench > samples.csv
cmake -S . -B build-san -DCMAKE_BUILD_TYPE=Debug -DENABLE_SANITIZERS=ON
cmake --build build-san
ctest --test-dir build-san --output-on-failure

本项目的构建开关(另估15分钟)

基础目标与编译选项读法沿用17。以下是配置文件中额外几行的操作说明;不需要实现CMake才能构建这个项目。

现有配置/命令 对这一次构建做什么
option(ENABLE_SANITIZERS "..." OFF) 定义一个布尔配置开关,首次默认关闭。配置时传-DENABLE_SANITIZERS=ON将它打开;CMake缓存会保留同一构建目录中的选择。
find_package(Threads REQUIRED) 查找当前平台的线程支持;必需依赖找不到时配置失败。
Threads::Threads 由查找结果提供的目标名,携带平台需要的线程编译/链接要求;不是一个需要自己创建的源码文件。
if(ENABLE_SANITIZERS)endif() 只在开关开启时为现有target加入列出的编译与链接选项;使用独立build-san目录保存此配置。
enable_testing()add_test(NAME learner_correctness COMMAND reduction_tests) 启用测试登记,将已有reduction_tests程序登记为learner_correctness。配置与登记本身不运行测试。
ctest --test-dir build --output-on-failure 从build目录执行已登记测试;失败时显示它的输出。应在构建成功后执行,检查实际返回状态;未实现的starter会失败。

三个构建目录可分别保留Debug、Release和sanitizer配置;修改源码后仍须构建相应目标。sanitizer的验证边界见18.4。这15分钟是操作阅读粗估,另加到原项目预算;它不代表学习者实现已经通过。

操作依据:CMake optionFindThreadsadd_testCTest命令

4 · Measure only after correctness

Before reading benchmark.cpp, complete NET N6’s time-point/duration chain and Chapter 30’s nanosecond reading and measurement boundaries. The full tests.cpp has no chrono call; this prerequisite prepares the subsequent benchmark, rather than attributing a nonexistent API to the tests.

The benchmark validates each result outside its timed region and performs a warm-up before seven samples per size/worker combination. Record compiler, flags, OS, CPU, power mode and background load alongside CSV. Compare like with like; the benchmark includes thread creation when workers > 1. Its supplied sizes start at 1000, so the required zero-input correctness case belongs in your earlier tests; do not claim that benchmark.cpp already measures it. Do not infer device properties from the numbers.

Finish with your prediction, code, independent tests, partition drawing, raw samples and a five-minute explanation using a new input/worker variation. The teaching examples have answers; this starter intentionally does not. This documentation-only migration changed no CPP, HPP, TODO, CMake configuration, runner, execution receipt or personal mastery record.

五分钟英文项目答辩

  1. Problem:输入合同、目标和必须保持的正确性是什么?
  2. Design:为什么采用这种划分?数据由谁拥有?
  3. Validation:测试覆盖哪些边界,仍有哪些限制?
  4. Measurement:计时范围是什么?原始样本和环境在哪里?
  5. Trade-off:什么情况下更多线程会变慢?下一步如何验证?
I started with a precise input contract and a sequential reference. I then partitioned the work and tested boundary sizes and worker counts. The measurements describe this CPU and this timed region; I have not validated performance on an accelerator.

行为问题也用真实事例回答

选择真实发生的工作或学习事件。按背景、责任、具体行动、结果和反思组织,不编造数字或把示例经历当作个人经历。

MacPerf 怎么接上来

MacPerf 的计时、缓存、虚拟内存和并发主题可辅助理解;完整 A00–A09 重建是共同路线完成后的一个专项选项。原有 reference gate 和作者证据要求继续有效,不能把教材例子或 Reduction Lab 的结果当作 MacPerf 的完成记录。

返回唯一学习路线 →