Saya memiliki loop for berikut, yang berisi panggilan fungsi pribadi di dalamnya:

for (i = 0; i < N; ++i)
    dates[i] = to_time_t(&string_dates[i][0]);

to_time_t hanya mengonversi string (e.g.: "18/03/2007") menjadi stempel waktu, dan ia melakukannya dengan bantuan mktime(), yang sangat lambat. Faktanya, for loop saja membutuhkan waktu paling banyak dari kode lain dalam program. Untuk mengatasinya, saya mencoba menerapkan OpenMP ke loop, seperti ini:

#pragma omp parallel for private(i)
for (i = 0; i < N; ++i)
    dates[i] = to_time_t(&string_dates[i][0]);

Pengetahuan OpenMP saya terbatas, tetapi saya berasumsi bahwa setiap elemen larik dates tidak pernah diakses oleh dua utas secara bersamaan karena i bersifat pribadi. Hal yang sama harus berlaku untuk string_dates. Tetapi ketika saya menjalankan kode ini, kinerjanya sebenarnya lebih buruk, jadi saya pasti melakukan sesuatu yang salah, saya tidak melihatnya. Bantuan apa pun dihargai!

Sunting: Saya seharusnya memasukkan kode to_time_t dari awal.

time_t to_time_t(const string * date) {
    struct std::tm tm = {0};

    istringstream ss_tm(*date);
    ss_tm >> get_time(&tm, "%m/%d/%Y");

    return mktime(&tm);
}
0
Rahman Khalaf 28 Mei 2020, 20:50

1 menjawab

Jawaban Terbaik

Masalahnya ada di mktime() yang memiliki efek samping di seluruh proses. Dari halaman manual:

Memanggil mktime() juga menyetel variabel eksternal tzname dengan informasi tentang zona waktu saat ini.

mktime() panggilan internal tzset(). Yang terakhir diserialkan melalui kunci mutex, tetapi yang benar-benar memperlambatnya dalam kasus multithreaded adalah cache yang terus-menerus dibuang. Saat panggilan ke tzset() oleh utas yang berjalan pada inti CPU tertentu menulis ke tzname, ini membatalkan cache semua inti lainnya, memaksa utas yang berjalan pada inti tersebut untuk mengakses tingkat cache yang lebih tinggi atau bahkan memori utama saat berikutnya ada panggilan ke mktime().

Anda perlu menemukan atau menulis padanan mktime() yang tidak mengubah status global. Atau tetap berpegang pada eksekusi berurutan untuk bagian kode itu. Tidak apa-apa untuk memanggil mktime() secara bersamaan dalam beberapa proses sekuensial (misalnya, dalam aplikasi MPI murni).

1
Hristo 'away' Iliev 30 Mei 2020, 08:29