- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作 MT Ray-Tracer 多线程,正如标题所说,它的执行时间是单线程版本的两倍。显然目的是将渲染时间缩短一半,然而我现在所做的只是让光线追踪方法运行两次,每个线程一次,基本上是将相同的渲染执行两次。尽管如此,由于线程可以并行运行,因此执行时间不会有明显的增加。但是是关于加倍。
这必须与我的多线程设置有关。我认为这与我将它们创建为可连接的事实有关。因此,我将解释我在做什么,并将相关代码放在一起,看看是否有人可以确认这是否是问题所在。
我创建了两个线程并将它们设置为可连接。创建一个 RayTracer,分配足够的内存来存储图像像素(这是在构造函数中完成的)。运行两次迭代循环以发送每个线程的相关信息,例如线程 ID 和 Raytracer 实例的地址。
然后pthread_create调用run_thread,其目的是在工作完成的地方调用ray_tracer:draw方法。在 draw 方法上,我有一个
pthread_exit (NULL);
作为它上面的最后一件事(上面唯一的 MT 东西)。然后再做一个循环加入线程。最后我开始在一个小循环中写入文件。最后关闭文件,删除draw方法中用来存放图像的数组相关的指针。
我现在可能不需要使用加入,因为我不是在做一个“真正的”多线程光线追踪器,只是渲染它两次,但是一旦我开始在图像像素之间交替(即线程 0 -> 渲染像素 0 - 线程 0 -> 存储像素 0,线程 1 -> 渲染像素 1 - 线程 1 -> 存储像素 1,线程 0 -> 渲染像素 2 - 线程 0 -> 存储像素 2,线程 1 -> 渲染像素 3 - 线程 1 -> 存储像素 3,等等...)我我想我需要它以便能够在文件中以正确的顺序写入像素。
这样对吗?我真的需要在我的方法(或任何其他方法)中使用 join here 吗?如果我这样做,我怎样才能让线程同时运行,而不是等待另一个线程完成?这个问题与加入完全无关吗?
pthread_t threads [2];
thread_data td_array [2];
pthread_attr_t attr;
void *status;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
TGAManager tgaManager ("z.tga",true);
if (tgaManager.isFileOpen()) {
tgaManager.writeHeadersData (image);
RayTracer rt (image.getHeight() * image.getWidth());
int rc;
for (int i=0; i<2; i++) {
//cout << "main() : creating thread, " << i << endl;
td_array[i].thread_id=i;
td_array[i].rt_ptr = &rt;
td_array[i].img_ptr = ℑ
td_array[i].scene_ptr = &scene;
//cout << "td_array.thread_index: " << td_array[i].thread_id << endl;
rc = pthread_create (&threads[i], NULL, RayTracer::run_thread, &td_array[i]);
}
if (rc) {
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
pthread_attr_destroy(&attr);
for (int i=0; i<2; i++ ) {
rc = pthread_join(threads[i], &status);
if (rc) {
cout << "Error:unable to join," << rc << endl;
exit(-1);
}
}
//tgaManager.writeImage (rt,image.getSize());
for (int i=0; i<image.getWidth() * image.getHeight(); i++) {
cout << i << endl;
tgaManager.file_writer.put (rt.b[i]);
tgaManager.file_writer.put (rt.c[i]);
tgaManager.file_writer.put (rt.d[i]);
}
tgaManager.closeFile(1);
rt.deleteImgPtr ();
}
最佳答案
你确实想要 join() 线程,因为如果你不这样做,你会遇到几个问题:
您如何知道线程何时完成执行?您不希望开始写出结果图像时才发现它在您写出时还没有完全计算出来。
您如何知道何时可以安全地拆除线程可能正在访问的任何数据结构?例如,您的 RayTracer
对象在堆栈上,并且(AFAICT)您的线程正在写入其像素数组。如果您的主函数在线程退出之前返回,则很有可能线程有时最终会写入不再存在的 RayTracer
对象,这将通过覆盖任何内容来破坏堆栈在您的函数返回后,其他对象可能(偶然)存在于这些相同位置。
所以你肯定需要 join() 你的线程;不过,您不需要将它们显式声明为 PTHREAD_CREATE_JOINABLE,因为该属性无论如何都已默认设置。
加入线程不应导致线程变慢,只要创建并运行两个线程之前您对其中任何一个调用 join()(这在您的发布代码)。
至于为什么您会看到两个线程速度变慢,这很难说,因为速度减慢可能来自多个地方。一些可能性:
您的光线追踪代码中的某些东西正在锁定一个互斥量,这样对于大部分光线追踪运行来说,无论如何一次只允许两个线程中的一个执行。
<两个线程大约同时写入相同的内存位置,这会导致缓存争用,从而减慢两个线程的执行速度。
我的建议是设置线程,使线程 #1 仅渲染图像的上半部分,而线程 #2 仅渲染图像的下半部分;这样,当他们写入输出时,他们将写入不同的内存部分。
如果这没有帮助,您可以暂时将渲染代码替换为更简单的代码(例如,将像素设置为随机值的“渲染器”),看看是否可以加速。如果是这样,那么您的 RayTracer
实现中可能存在不支持多线程的内容。
关于c++ - 不完整的多线程 RayTracer 花费的时间是预期的两倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50125322/
您好,我是使用 xampp 的 PHPmyadmin 新手,没有 MYSQL 背景。当我喜欢研究它是如何工作的时,我的脑海中浮现出一个想法,它让我一周都无法休眠,因为我似乎无法弄清楚如何使用 MIN(
Go docs say (强调): Programs using times should typically store and pass them as values, not pointers.
我有一组用户在 8 月 1 日有一个条目。我想找到在 8 月 1 日有条目但在 8 月 2 日没有做任何事情的用户。 现在是 10 月,所以事件已经过去很久了。 我有限的知识说: SELECT * F
我有以下代码,主要编码和取消编码时间结构。这是代码 package main import ( "fmt" "time" "encoding/json" ) type chec
您能详细解释一下“用户 CPU 时间”和“系统 CPU 时间”吗?我读了很多,但我不太理解。 最佳答案 区别在于时间花在用户空间还是内核空间。用户 CPU 时间是处理器运行程序代码(或库中的代码)所花
应用程序不计算东西,但做输入/输出、读取文件、使用网络。我希望探查器显示它。 我希望像 callgrind 中的东西一样,在每个问题中调用 clock_gettime。 或者像 oprofile 那样
目前我的 web 应用程序接收 websocket 数据来触发操作。 这会在页面重新加载时中断,因此我需要一个能够触发特定事件的客户端解决方案。 这个想法可行吗? 假设你有 TimeX = curre
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我有一个 Instant (org.joda.time.Instant) 的实例,我在一些 api 响应中得到它。我有另一个来自 (java.time.Instant) 的实例,这是我从其他调用中获得
如何集成功能 f(y) w.r.t 时间;即 'y'是一个包含 3000 个值和值 time(t) 的数组从 1 到 3000 不等。所以,在整合 f(y) 后我需要 3000 个值. 积分将是不确定
可以通过 CLI 创建命名空间,但是如何使用 Java SDK 来创建命名空间? 最佳答案 它以编程方式通过 gRPC API 完成由服务公开。 在 Java 中,生成的 gRPC 客户端可以通过 W
我有一个函数,它接受 2 组日期(开始日期和结束日期),这些日期将用于我的匹配引擎 我必须知道start_date1和end_date1是否在start_date2和end_date2内 快进:当我在
我想从 Python 脚本运行“time”unix 命令,以计算非 Python 应用程序的执行时间。我会使用 os.system 方法。有什么方法可以在Python中保存这个输出吗?我的目标是多次运
我正在寻找一种“漂亮的数字”算法来确定日期/时间值轴上的标签。我熟悉 Paul Heckbert's Nice Numbers algorithm . 我有一个在 X 轴上显示时间/日期的图,用户可以
在 PowerShell 中,您可以格式化日期以返回当前小时,如下所示: Get-Date -UFormat %H 您可以像这样在 UTC 中获取日期字符串: $dateNow = Get-Date
我正在尝试使用 Javascript 向父子窗口添加一些页面加载检查功能。 我的目标是“从父窗口”检测,每次子窗口完全加载然后执行一些代码。 我在父窗口中使用以下代码示例: childPage=wi
我正在尝试设置此 FFmpeg 命令的 drawtext 何时开始,我尝试使用 start_number 但看起来它不会成功。 ffmpeg -i 1.mp4 -acodec aac -keyint_
我收到了一个 Excel (2010) 电子表格,它基本上是一个文本转储。 单元格 - J8 具有以下信息 2014 年 2 月 4 日星期二 00:08:06 EST 单元格 - L8 具有以下信息
我收到的原始数据包含一列具有以下日期和时间戳格式的数据: 2014 年 3 月 31 日凌晨 3:38 单元格的格式并不一致,因为有些单元格有单个空格,而另一些单元格中有两个或三个字符之间的空格。所以
我想知道是否有办法在我的 Grails 应用程序顶部显示版本和构建日期。 编辑:我应该说我正在寻找构建应用程序的日期/时间。 最佳答案 在您的主模板中,或任何地方。 Server version:
我是一名优秀的程序员,十分优秀!