当前位置: 首页 > news >正文

如何推销企业建设网站招聘网站排名

如何推销企业建设网站,招聘网站排名,武汉市人民政府新闻发布会,杭州广告公司有哪些并行算法 1. 核心知识点2. 使用并行算法3. 数据竞争与线程安全4. 性能优化5. 常见问题与陷阱6. 最佳实践7. 多选题7.1 题目7.2 多选答案 9. 设计题目10. 设计题目答案 1. 核心知识点 执行策略(Execution Policies) C17引入的执行策略允许开发者指定算法…

并行算法

    • 1. 核心知识点
    • 2. 使用并行算法
    • 3. 数据竞争与线程安全
    • 4. 性能优化
    • 5. 常见问题与陷阱
    • 6. 最佳实践
    • 7. 多选题
      • 7.1 题目
      • 7.2 多选答案
    • 9. 设计题目
    • 10. 设计题目答案

1. 核心知识点

  1. 执行策略(Execution Policies)
    C++17引入的执行策略允许开发者指定算法的并行方式,主要分为三类:
    std::execution::seq:顺序执行(无并行)
    std::execution::par:多线程并行
    std::execution::par_unseq:允许向量化指令和跨线程交错执行的并行
  2. 关键点
    选择par时需保证操作是线程安全的。
    par_unseq需函数无数据竞争且可向量化。
    不支持并行执行的算法默认会退化为顺序执行。

2. 使用并行算法

原有标准库算法(如sort, for_each)通过添加执行策略参数实现并行化:

#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>int main() {// 初始化测试数据std::vector<int> data = {5, 3, 8, 1, 2, 7, 4, 6};// 输出排序前的数据std::cout << "Before sorting: ";for (int num : data) {std::cout << num << " ";}std::cout << std::endl;// 并行排序std::sort(std::execution::par, data.begin(), data.end());// 输出排序后的数据std::cout << "After sorting: ";for (int num : data) {std::cout << num << " ";}std::cout << std::endl;// 输出遍历前的数据std::cout << "Before parallel for_each: ";for (int num : data) {std::cout << num << " ";}std::cout << std::endl;// 并行遍历,将每个元素乘以 2std::for_each(std::execution::par, data.begin(), data.end(), [](int& x) {x *= 2;});// 输出遍历后的数据std::cout << "After parallel for_each: ";for (int num : data) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

3. 数据竞争与线程安全

问题:并行操作共享数据可能导致未定义行为。
解决

  • 避免修改共享状态,使用线程本地存储(TLS)。
  • 使用原子操作或互斥锁(可能抵消并行优势)。

4. 性能优化

  • 粒度控制:任务过细会导致调度开销,过粗则负载不均。
  • 数据局部性:优化内存访问模式,减少缓存失效。

代码:并行std::transform

#include <vector>
#include <execution>
#include <algorithm>
#include <iostream>int main() {std::vector<int> input = {1, 2, 3, 4, 5};std::vector<int> output(input.size());// 输出输入向量std::cout << "Input vector: ";for (int num : input) {std::cout << num << " ";}std::cout << std::endl;// 并行转换:每个元素平方std::transform(std::execution::par,input.begin(), input.end(),output.begin(),[](int x) { return x * x; });// 输出输出向量std::cout << "Output vector after parallel transformation: ";for (int num : output) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
/*
std::execution::par指示并行执行。
Lambda函数需线程安全,不可修改外部变量。
输出迭代器必须有效且不重叠。
*/

代码:并行std::for_each与竞态处理

#include <vector>
#include <execution>
#include <atomic>
#include<iostream>int main() {std::vector<int> data(1000, 1);std::atomic<int> sum = 0;// 并行求和(原子操作避免竞态)std::for_each(std::execution::par,data.begin(), data.end(),[&sum](int x) { sum += x; });// 输出结果:1000std::cout << "Sum: " << sum << std::endl;
}
/*
- 使用std::atomic确保线程安全的累加。
- 无锁设计可提升性能,但需权衡实现复杂度。
*/

5. 常见问题与陷阱

  1. 不可用的迭代器:
  • 输入/输出迭代器在并行期间必须保持有效且不重叠。
#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>int main() {try {std::vector<int> v = {1, 2, 3};v.reserve(100);std::cout << "Before parallel for_each, vector size: " << v.size() << std::endl;// 错误:v在并行过程中被修改std::for_each(std::execution::par, v.begin(), v.end(), [&](int x) {v.push_back(x);});std::cout << "After parallel for_each, vector size: " << v.size() << std::endl;std::cout << "Vector elements after operation:" << std::endl;for (int num : v) {std::cout << num << " ";}std::cout << std::endl;} catch (const std::exception& e) {std::cerr << "Exception caught: " << e.what() << std::endl;}return 0;
}    
  1. 异常处理:
  • 并行算法中未捕获的异常会导致std::terminate。
  • 使用try-catch块需注意执行策略是否允许。

6. 最佳实践

  1. 基准测试:
  • 比较并行与串行性能,确保并行带来收益。
#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>
#include <chrono>
#include <random>int main() {// 定义向量大小const int size = 1000000;// 创建包含随机数据的向量std::vector<int> data(size);std::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<> dis(1, 1000000);// 填充随机数据for (int i = 0; i < size; ++i) {data[i] = dis(gen);}// 记录开始时间auto start = std::chrono::high_resolution_clock::now();// 并行排序std::sort(std::execution::par, data.begin(), data.end());// 记录结束时间auto end = std::chrono::high_resolution_clock::now();// 计算并输出排序所花费的时间auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);std::cout << "Time: " << duration.count() << " ns\n";return 0;
}    
  1. 选择合适的执行策略:
  • par适用于CPU密集型任务。
  • par_unseq适合SIMD指令优化的场景(如数值计算)。

7. 多选题

7.1 题目

  1. 下列关于C++17执行策略的说法错误的是:
    A. std::execution::seq 保证算法完全顺序执行,等同于传统非并行版本。
    B. std::execution::par 允许在多个线程中并行执行,但同一线程内的操作必须顺序执行。
    C. std::execution::par_unseq 允许跨线程和向量化(如SIMD指令)的并行执行。
    D. 使用par_unseq策略时,访问共享资源的代码必须是无锁的。

  2. 以下场景适合使用并行算法的是:
    A. 对std::list中的每个元素进行独立数学计算。
    B. 对std::vector进行快速排序。
    C. 遍历一个树结构,修改每个节点的值。
    D. 对两个数组进行逐元素相加,结果存储到第三个数组。

  3. 关于并行算法中的异常处理,正确的是:
    A. 并行算法中多个元素抛出的异常会被合并为一个std::exception_list对象。
    B. 使用并行执行策略时,未捕获的异常会直接终止程序。
    C. std::execution::par策略的并行算法中,一旦某个元素抛出异常,其他所有操作会立即停止。
    D. 只有seq策略支持异常传播。

  4. 下列代码的潜在问题是:

    std::vector<int> vec(1000, 1);
    int sum = 0;
    std::for_each(std::execution::par, vec.begin(), vec.end(), [&](int x) { sum += x; });
    

    A. 性能不如串行版本。
    B. 会导致数据竞争。
    C. 可以正确累加求和。
    D. 违反了par_unseq的内存访问规则。

  5. 关于自定义并行任务的设计,正确的说法是:
    A. 可以通过继承std::thread实现更灵活的线程池。
    B. 与标准库并行算法相比,手动线程池在任务分配上更高效。
    C. C++17的并行算法必须依赖std::execution策略,无法扩展。
    D. std::async的异步策略可以替代并行算法的所有功能。

7.2 多选答案

  1. 答案:B
    解析:std::execution::par允许跨线程并行,同一线程内的操作可能被调度打断(如任务窃取),不保证顺序。par_unseq还要考虑向量化的无序执行(例如SIMD指令),D正确(因par_unseq要求无锁)。

  2. 答案:B, D
    解析:快速排序的分治特性适合并行(如std::sort(par, …))。选项D的数据独立性也适合。A错误(std::list迭代器不是随机访问,不支持并行策略)。C错误(树结构遍历存在依赖)。

  3. 答案:A
    解析:C++17中,并行算法抛出的多个异常会由std::terminate终止,但规范未明确定义exception_list的实现(某些库可能支持A)。B错误(未定义行为)。C错误(不保证立即停止)。

  4. 答案:B
    解析:sum += x存在数据竞争,需用原子变量或归约操作。D中的问题在于par_unseq的内存访问需要无副作用,但此处的问题独立于策略。

  5. 答案:B
    解析:B正确(手动优化可能更好)。C错误(可通过自定义执行器扩展)。D错误(std::async不直接提供并行算法的高层抽象)。

9. 设计题目

  1. 使用std::sort的并行版本对大型std::vector进行排序,并与串行版本对比时间。
    要求:生成随机数填充容器,输出两种策略的排序耗时。

  2. 实现并行版本的std::transform,对两个std::vector进行逐元素相加,结果存入第三个容器。
    要求:不允许共享写入,测试不同数据规模下的正确性。

  3. 使用并行策略实现累加求和(类似std::accumulate),确保线程安全。
    要求:使用分段累加并合并结果,验证大数据的正确性。

  4. 在多线程环境下,利用并行算法处理图像滤镜(如反色处理)。
    要求:每个像素处理为独立任务,使用std::for_each的并行策略。

  5. 设计一个并行任务链:先对std::vector排序,再计算其前缀和。
    要求:使用std::execution策略,确保依赖关系正确处理。

10. 设计题目答案

// 1. 
#include <algorithm>
#include <vector>
#include <random>
#include <chrono>
#include <execution>
#include <iostream>int main() {const size_t data_size = 1'000'000;std::vector<int> data_serial(data_size);std::vector<int> data_parallel(data_size);// 生成随机数std::mt19937 gen{std::random_device{}()};std::uniform_int_distribution<int> dist(1, 1000);auto rand_gen = [&] { return dist(gen); };std::generate(data_serial.begin(), data_serial.end(), rand_gen);data_parallel = data_serial;// 串行排序计时auto start_serial = std::chrono::high_resolution_clock::now();std::sort(data_serial.begin(), data_serial.end());auto end_serial = std::chrono::high_resolution_clock::now();std::chrono::duration<double> elapsed_serial = end_serial - start_serial;// 并行排序计时auto start_parallel = std::chrono::high_resolution_clock::now();std::sort(std::execution::par, data_parallel.begin(), data_parallel.end());auto end_parallel = std::chrono::high_resolution_clock::now();std::chrono::duration<double> elapsed_parallel = end_parallel - start_parallel;std::cout << "Serial sort time: " << elapsed_serial.count() << "s\n";std::cout << "Parallel sort time: " << elapsed_parallel.count() << "s\n";
}/*
使用std::execution::par策略激活并行排序
生成百万级随机测试数据确保可见性能差异
需包含<execution>头文件启用并行策略
输出显示并行版本通常比串行快2-5倍(取决于核心数)
实际结果需在支持并行执行的编译器环境中测试
*/// 2. 
#include <vector>
#include <execution>
#include <iostream>
#include <numeric>void test_transform(size_t N) {std::vector<double> a(N), b(N), result(N);std::iota(a.begin(), a.end(), 0);std::iota(b.begin(), b.end(), N);std::transform(std::execution::par, a.begin(), a.end(), b.begin(), result.begin(),[](double x, double y) { return x + y; });// 验证结果(取头尾样本)bool correct = (result[0] == 0+N) && (result.back() == (N-1)+(2*N-1));std::cout << N << " elements: " << (correct ? "Passed" : "Failed") << "\n";
}int main() {test_transform(1000);test_transform(1'000'000);test_transform(10'000'000);
}
// 3.
#include <vector>
#include <future>
#include <numeric>
#include <iostream>template<typename T>
T parallel_sum(const std::vector<T>& vec) {const size_t min_per_thread = 1000;const size_t max_threads = (vec.size() + min_per_thread - 1) / min_per_thread;const size_t hardware_threads = std::thread::hardware_concurrency();const size_t num_threads = std::min(hardware_threads != 0 ? hardware_threads : 2, max_threads);const size_t block_size = vec.size() / num_threads;std::vector<std::future<T>> futures;for(size_t i=0; i<num_threads; ++i) {auto start = vec.begin() + i*block_size;auto end = (i == num_threads-1) ? vec.end() : start + block_size;futures.push_back(std::async([=]{ return std::accumulate(start, end, T{}); }));}T total = 0;for(auto& f : futures)total += f.get();return total;
}int main() {std::vector<long> vec(10'000'000, 1); // 全1向量,和为10^7long sum = parallel_sum(vec);std::cout << "Sum: " << sum << " (Expected: 10,000,000)\n";
}
/*
使用std::transform搭配并行执行策略
lambda表达式定义元素级加法操作
无共享写入,各元素独立计算
测试不同数据规模的正确性
验证首尾元素确保整体正确
*/
// 4.
#include <vector>
#include <algorithm>
#include <execution>
#include <iostream>struct Pixel {unsigned char r = 0, g = 0, b = 0;void invert() {r = 255 - r;g = 255 - g;b = 255 - b;}
};int main() {// 生成测试数据(3x3图像)std::vector<Pixel> image(9);int val = 0;for (auto& p : image) {p.r = val;p.g = val + 50;p.b = val + 100;val += 20;}// 打印原始像素std::cout << "Original pixels:\n";for (const auto& p : image) {std::printf("(%3d,%3d,%3d) ", p.r, p.g, p.b);}// 并行反色处理std::for_each(std::execution::par, image.begin(), image.end(),[](Pixel& p) { p.invert(); });// 打印处理结果std::cout << "\n\nInverted pixels:\n";for (const auto& p : image) {std::printf("(%3d,%3d,%3d) ", p.r, p.g, p.b);}std::cout << "\n";return 0;
}
/*
利用std::for_each配合std::execution::par策略实现并行处理。
每个像素独立处理,无数据竞争,确保线程安全。
测试用例展示处理前后的像素变化,验证正确性。
*/// 5.
#include <vector>
#include <algorithm>
#include <execution>
#include <numeric>
#include <iostream>int main() {// 生成测试数据std::vector<int> vec{9, 3, 7, 1, 5};std::cout << "Original vector: ";for (int v : vec) std::cout << v << " ";// 并行排序(升序)std::sort(std::execution::par, vec.begin(), vec.end());// 计算前缀和(顺序执行,因C++标准库无并行partial_sum)std::vector<int> prefix(vec.size());std::partial_sum(vec.cbegin(), vec.cend(), prefix.begin());// 输出结果std::cout << "\nSorted vector: ";for (int v : vec) std::cout << v << " ";std::cout << "\nPrefix sums: ";for (int p : prefix) std::cout << p << " ";std::cout << "\n";return 0;
}/*
1.并行排序:使用std::sort的并行策略快速排序数组。
2.顺序前缀和:由于标准库无并行partial_sum,且计算依赖前序结果,故使用串行计算保证正确性。
3.依赖处理:显式确保排序完成后再计算前缀和,满足任务链的依赖关系。
*/
http://www.cadmedia.cn/news/9584.html

相关文章:

  • 电子商城网站建设流程400个成品短视频
  • 如何在网上接做网站的小项目苏州关键词排名系统
  • 网站建设怎么样工作百度爱采购平台官网
  • 江西网站建设开发石家庄seo
  • 外贸接单网站排名榜seo关键字优化教程
  • 黄金外汇网站建设百度上看了不健康的内容犯法吗
  • wordpress可以承受多大数据优化网站建设
  • dede建设网站教程手机怎么建自己的网站
  • 百度网站如何建设培训机构退费纠纷一般怎么解决
  • erp合同管理系统站长工具seo查询5g5g
  • 清溪镇网站建设公司疫情最新情况
  • 巩义网站建设今日热点新闻素材
  • 做网站的公司msgg百度竞价推广怎么做
  • 深圳nft网站开发公司it教育培训机构
  • 网上购物最实惠的网站全网搜索引擎优化
  • 网站建设报价单下载有道搜索引擎入口
  • 三明做网站的公司网站开发的公司
  • 网站开发类优惠及服务承诺磁力多多
  • 电子商务网站建设系统功能网站制作出名的公司
  • 创造app软件济南seo网站关键词排名
  • 专做热血电影的网站站内优化怎么做
  • 网站建设联系电话搜索引擎的网站
  • 网络运营部seo顾问合同
  • 河南建设工程信息网公众号seo技术公司
  • 建网站建设公司免费的网站推广在线推广
  • 网站建设公司织梦模板下载优化营商环境的措施建议
  • 如何在国际上做网站网络营销服务的特点有哪些
  • 成都建设网站费用站长之家素材网
  • 做网站需要融资seo搜索引擎优化试题
  • 烟店网站建设注册域名查询网站官网