質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

並列処理

複数の計算が同時に実行される手法

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

1回答

2365閲覧

MATLABにおける並列処理

Gotchara

総合スコア10

MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

並列処理

複数の計算が同時に実行される手法

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

0クリップ

投稿2020/10/04 07:15

編集2020/10/05 12:10

前提・実現したいこと

環境はMATLAB2019b, windows10です

現在、以下のようなプログラムを構築しようと考えております。

  1. 外部デバイスからの生体信号をMATLAB上で得続け、描画する
  2. 生体信号にて特定の波形が見つかったらトリガーを出すことを繰り返す
  3. トリガーが得られたら、特定の動作を行う。得られていない場合はほかの動作を繰り返す

そこで、1~2を合わせたものと3の内容の2つを並列処理させればいいのではと思いましたが、
並列処理を扱ったことがないため、関数parfevalを用いて簡易的なものを書いてみました。
内容は、動作1にて特定回数whileがまわるごとにtrig=1を送り、動作2ではtrigに基づきコメント表示するといったものを意図しました。

しかし、現状は動かしても"start"と表示されて以降音沙汰なく、エラーも表示されないため、どこが誤っているかもわからない状況になっております。

現在の問題解決、あるいは、本来の行いたい動作 (生体信号処理に関する1.~3.) を達成するために、お知恵をお貸しください。
今回はperfevalを用いておりますが、他に推奨される方法などがありましたら、お教えいただけますと幸いです
よろしくお願いいたします。

(10/5)
逐次処理で書いたものを追記いたしました。
parfevalを用いたものよりも、こちらで書いた内容のほうがより本来行いたい内容と近くなっております。

以下、行いたい動作の詳細になります。

  1. 生体信号の取得開始、figure表示
  2. +キーの呈示
  3. 生体信号にて特定波形が得られるまで待機。得られた場合にtrig=1とする
  4. trig==1の場合、画像Aを呈示する
  5. キー入力を求める[j/f]

6-1. キー入力を求められてから反応するまでの時間が<5sの場合: 画像B呈示
6-2. 5s>の場合: 画像Cを呈示
以後、2~6を繰り返す

該当のソースコード

clear; clc; global trig; global cnt; trig = 0; trig_cnt = 0; f = parfeval(@aaaa, 1, trig); disp('start') while 1 // 動作2 if trig == 1 trig_cnt = trig_cnt + 1; fprintf(1,'第 %d \n', trig_cnt); trig = 0; end end function aaaa(trig) // 動作1 global trig; global cnt; cnt = 1; disp('aaaa') while 1 cnt = cnt + 1; if mod(cnt, 5) == 0 trig = 1; fprintf(1,'trig %d \n', cnt); elseif cnt == 100 break; else trig = 0; end WaitSecs(0.5); end end

逐次処理

% 本来行いたかった処理を逐次処理にて書いたものです (簡略化しております)。 % 動作2におけるキー反応待機中も動作1を行いたいのですが、停止してしまうという問題が生じるため並列処理を考えておりました KbName('UnifyKeyNames'); F_Key = KbName('f'); J_Key = KbName('j'); trig_cnt = 1; % テクスチャーの作成 (追記) imgfile = ['./Resource/fixation.jpg']; imgdata = imread(imgfile); imgtexFixation = Screen('MakeTexture', mainWindow, imgdata); imgfile = ['./Resource/imgA.jpg']; imgdata = imread(imgfile); imgteximgA = Screen('MakeTexture', mainWindow, imgdata); imgfile = ['./Resource/imgB.jpg']; imgdata = imread(imgfile); imgteximgB = Screen('MakeTexture', mainWindow, imgdata); while 1 trig = 0; % 動作1 (省略しております) % 外部デバイスからの信号を得続け、figureに描画する Screen('DrawTexture', mainWindow, imgtexFixation); % +表示 Screen('Flip', mainWindow); % 特定の波形が検出されるたびにtrig=1にし、その時刻を記録する if 特定の波形 trig = 1; end % 動作2 if trig == 1 trig_cnt = trig_cnt + 1; fprintf(1,'第 %d \n', trig_cnt); RT_start = GetSecs; KeyOn = 0; while KeyOn == 0 % キー入力があるまで待機 time_stim_presn_ed = GetSecs; [keyDown, secs, keycode] = KbCheck; if keycode(J_Key) || keycode(F_Key) KeyOn = 1; Screen('DrawTexture', mainWindow, imgteximgA); % 画像A呈示 Screen('Flip', mainWindow); break; % elseifを追記しました elseif round((time_stim_presn_ed-RT_start)*1000) >= 5000 % 5s(5000ms)反応がない場合 Screen('DrawTexture', mainWindow, imgteximgB); % 画像B呈示 Screen('Flip', mainWindow); break; end end RT = round((secs-RT_start)*1000); % 反応時間(ms)算出 disp(RT) end end

試したこと

どこで実行が止まっているかを確認するために、dispやfprintfをいたるところに入れて問題の抽出を行おうとしました。
結果、disp('start')のみが表示されています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

質問文等から察するにプログラミング自体の初心者なのだと思いますが、並列処理は初心者には荷が重いのでやめたほうがいいと思います。まずは素直に逐次処理にすればいいかと

追記

やりたいことの優先順位をつけずに、思いついた順番でやろうとするから話がややこしくなるのです。
要するに、トリガーの検出処理と、キー入力にかかった時間の計算処理は、同時にする必要がないですよね?

測定用のプログラムと分析用のプログラムの2つに分け、
測定用のプログラムでは、trig==1のタイミングとキー入力のタイミングを全部ファイルに記録する。
分析用のプログラムでは、記録したファイルから、キー入力にかかった時間を計算する。

とすれば、測定の記録は正確に残るし、あとからいくらでも内容の検証ができます。

追記2

コードを書く気力がもうないので一部だけ擬似コードで書きます。これ以上の後出しジャンケンは受け付けません。
結局の所、「待機したら動作1が止まってしまうのが問題なら、待機しなければいい」これがすべてです。

matlab

1while 2 % 動作1 34 % 動作2 5 if trig==1 && ~キー入力待ち 6 トリガーされた時刻=7 キー入力待ちをセット 8 end 9 if キー入力待ち 10 if トリガーされた時刻から5秒過ぎた 11 画像Bを提示 12 キー入力待ちをリセット 13 elseif キー入力された 14 画像Aを提示 15 キー入力待ちをリセット 16 end 17 end 18emd

投稿2020/10/05 06:48

編集2020/10/05 13:28
yuki23

総合スコア1448

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Gotchara

2020/10/05 07:49

ご回答くださり、ありがとうございます。 おっしゃる通り初心者ですので、はじめは逐次処理にて行ってみました。 (本文に逐次処理のものを追記いたしましたので、参照ください) しかし、逐次処理の場合には動作2のキー反応待機時間により動作1が思うように動かない結果になりましたので、解決するために並列処理を用いることを考え、質問させていただいた次第でした。 情報を後出しするような形になってしまい、申し訳ございませんが、 並列処理を用いなくても解決できる方法がありましたら、お教えいただけますと幸いです。よろしくお願いいたします。
yuki23

2020/10/05 08:06

これでは何がやりたいのかさっぱりわかりません。 待機したら動作1が止まってしまうのが問題なら、待機しなければいいのでは?
yuki23

2020/10/05 08:15

もしかして、trig==1になってからキー入力されるまでの時間を測りたいということですか?
Gotchara

2020/10/05 08:48

ご指摘の通り、本来はtrig==1になってからキー入力されるまでの時間測定を行うものです。 本文にて時間測定 (反応時間) を行うための内容を追記いたしました。
yuki23

2020/10/05 09:12

測定した反応時間は動作1の中で使うんでしょうか? それとも単に記録するだけですか?
Gotchara

2020/10/05 09:19

記録するのみになります。
yuki23

2020/10/05 09:58

回答追記しました
Gotchara

2020/10/05 12:09

大変申し訳ございません。反応時間の結果は動作1では用いませんが、動作2にて得られた反応時間をもとに返す反応を変更させる必要性がありました。 キー入力を求めてから5s以上反応がなければ画像Bを呈示する。5s以内に反応があれば画像Aを呈示というものであり、トリガー検出処理と反応時間の計算処理は同時に行う必要がありました。 この場合、5sを測定するために本文に記したようなwhileがいるかと思いますが、他の方法で使用を回避することはできますでしょうか。 (一番外側のwhileを1周するために50ms以上はかかってしまうため、それを用いて5sを正確に測定することは難しく思われました) 本文に行いたい動作の詳細を追記し、それを踏まえ逐次処理の内容も修正いたしました。 情報が小出しになってしまったことにより、ご迷惑をおかけしてしまいましたこと、重ね重ねお詫び申し上げます。
yuki23

2020/10/05 13:28

回答2追記しました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問